vue.jsvuejs3vue-routervue-router4

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?


Solution

  • 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" ] }