Nala
Nala

Reputation: 15

Escape colon in Vue router wikipedia-style

Context

I've been trying to replicate what wikipedia does with their URL

It works something like

/[Namespace]:[PageName]

/[PageName]

So if I go to /randompage I get as params:

and if I go to /whatever:anotherpage I get:

Problem

My issue lies in not being able to escape the colon :. For example, if I use - instead the route string is as simple as :namespace-:pagename. I tried doing :namespace::pagename and got very weird results. As an example, when I tried to match /hi:bye I got as namespace h and as page name i:bye (see this). Similar results with everything else I tried (:template\\::pagename, :template()\\::pagename).

What's the proper way of handling this issue in Vue Router?

Upvotes: 1

Views: 84

Answers (1)

imhvost
imhvost

Reputation: 9793

You can specify the regular expression ([^:]+) which will capture all characters up to the colon paths.esm.dev:

/:namespace([^:]+):pagename

In this case pagename will be :bye. If the colon in this parameter will bother you, then you can get rid of it, for example, when the route is defined, like this:

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
   {
    path: '/:namespace([^:]+):pagename(.+)',
    name: 'routeName',
    component: TheComponent,
    beforeEnter: (to, from, next) => {
      if (to.params.pagename) {
        to.params.pagename = String(to.params.pagename).replace(/^:/, '');
      };
      next();
    }
   },
  ],
});

You can also collect any options separated by colons without specifying them in path:

{
  path: '/:page',
  name: 'routeName',
  component: TheComponent,
  beforeEnter: (to, from, next) => {
    if (to.params.page) {
      const params = String(to.params.page).split(':');
      to.params = { params };
    }
    next();
  }
}

In this case, in route /hi:bye:anything, you will get { "params": [ "hi", "bye", "anything" ] }

Upvotes: 1

Related Questions