swup/js-plugin

Regex option does not work for me

trych opened this issue · 4 comments

trych commented

Description of the issue

I am trying to use the regex option for routing, but it does not work correctly.
I have a routing setup that worked as follows without regex:

const options = [
  {
    // home to any other page
    from: '/',
    to: '(.*)',
    out: next => next(),
    in: next => next()
  },
  {
    // any other page to home
    from: '(.*)',
    to: '/',
    out: next => next(),
    in: next => next()
  },
];

Now, this works fine. However, I need to host my setup on a staging server, where the home page is basically in a subfolder /foo instead of /. To make it work both in my local setup as well as on the staging server I thought I can use a regex, so I did this:

const options = [
  {
    // home to any other page
    from: /\/(foo)?/, // match '/' or '/foo'
    to: '(.*)',
    out: next => next(),
    in: next => next()
  },
  {
    // any other page to home
    from: '(.*)',
    to: /\/(foo)?/, // match '/' or '/foo',
    out: next => next(),
    in: next => next()
  },
];

This works fine when I use it in my local setup, where it animates from / to any other page, but it does not work on my staging server when I want to animate from the home page at /foo to any other page. In this case it always runs the second route option where it animates back from any page to the home page.

Happens in current Firefox, Chrome and Safari browsers. I use swup 3.0.4 and the swup Js plugin 1.0.5.

Any ideas what could be going wrong? Or am I setting this up incorrectly?

Your regex is matching too many scenarios: https://regex101.com/r/3UAcPK/1

You should make it more rigid, with trailing slash and ^ / $. Here is an example:

/**
 * Matches either exactly "/", "/foo/" or "/foo" 
 * @see https://regex101.com/r/W9EccH/4
 */
const homeRegex = /^\/(foo)?\/?$/i;

const options = [
  {
    // home to any other page
    from: homeRegex,
    to: '(.*)',
    out: next => next(),
    in: next => next()
  },
  {
    // any other page to home
    from: '(.*)',
    to: homeRegex,
    out: next => next(),
    in: next => next()
  },
];

Did some more digging... JS Plugin uses the package path-to-regexp. From their documentation: https://github.com/pillarjs/path-to-regexp#path-to-regexp-1, you can simply use and array of paths:

const options = [
  {
    // home to any other page
    from: ["/", "/foo/"],
    to: "(.*)",
    out: next => next(),
    in: next => next()
  },
  {
    // any other page to home
    from: "(.*)",
    to: ["/", "/foo/"],
    out: next => next(),
    in: next => next()
  },
];
trych commented

Thank you so much @hirasso for having a look at this and sorry that I was obviously misunderstanding my own regex. 🙈

Both proposed solutions work really well, I will go with the latter one, that one is very clean and easy to read. Might I suggest to include this into the docs? I could offer to prepare a PR if this should be included.

Happy this helped. Yes, good idea creating a PR for that! 👍