preactjs / preact-router

:earth_americas: URL router for Preact.
http://npm.im/preact-router
MIT License
1.02k stars 155 forks source link

Force trailing slash for routes #363

Closed gilomen2 closed 4 years ago

gilomen2 commented 4 years ago

Is it possible to force all routes to redirect to on match to the path plus a trailing slash?

teodragovic commented 4 years ago

You can do that using onChange handler:

import { Router, route } from 'preact-router';

const App = () => {

  const handleRoute = e => {
    if (e.url.slice(-1) !== '/') {
        route(`${e.url}/`, true);
    }
  };

  return (
    <Router onChange={handleRoute}>
      <Home path="/" />
      <Profile path="/profile" />
    </Router>
  );

};

I'm probably missing some edge cases here, but this would be the basic idea.

developit commented 4 years ago

That's pretty much the idea, yep. It's not perfect though, since route() will cause it to render again.

You can fix that by using the history API directly:

import { Router, route } from 'preact-router';

function ensureTrailingSlash({ url }) {
    if (url.slice(-1) !== '/') {
        history.replaceState(null, null, url + '/');
    }
};

function App() {
  return (
    <Router onChange={ensureTrailingSlash}>
      <Home path="/" />
      <Profile path="/profile" />
    </Router>
  );
};
developit commented 4 years ago

FWIW I'm open to an option to add this, I'm just not super convinced it can be done in a way that is better than server-side redirects / Service Worker / history interception.