Skip to main content

FAQ

How do I add a No Match (404) Route in ArchibaldRouter?

<Route path="*" element={<NoMatch />} />

You can also define No Match Route per your nested block (the closest one will be used):

<Routes>
<Route path="/:language?" element={<Layout />}>
<Route index element={<HomePage />} fallback={<TestHomePlaceholder />} />
<Route path="p/:productId(\d+)" element={<ProductDetailPage />} />
<Route path="s">
<Route path=":first-:second" element={<SearchPage />} />
<Route index element={<SearchPage />} />
<Route path="*" element={<SearchNoMatch />} />
</Route>
<Route path="*" element={<GlobalNoMatch />} />
</Route>
</Routes>

Which will result into:

URLElement
"/"<HomePage />
"/de"<HomePage />
"/de/p/007"<ProductDetailPage />
"/de/s"<SearchPage />
"/de/s/one-two"<SearchPage />
"/de/s/none"<SearchNoMatch />
"/de/checkout"<GlobalNoMatch />

<Route> doesn't render? How do I compose?

In ReactRouter v5 the <Route> component was just a normal component that was like an if statement that rendered when the URL matched its path. In ArchibaldRouter, a <Route> element doesn't actually ever render, it's simply there for configuration.

In ReactRouter v5, since routes were just components, MyRoute will be rendered when the path is "/my-route".

// ReactRouter v5 app
const App = () => (
<div>
<MyRoute />
</div>
);

const MyRoute = ({ element, ...rest }) => {
return <Route path="/my-route" children={<p>Hello!</p>} />;
};

In ArchibaldRouter, however, the <Route> is only used for its props, so the following code will never render <p>Hello!</p> because <MyRoute> has no path that <Routes> can see:

const App = () => (
<Routes>
<MyRoute />
</Routes>
);

const MyRoute = () => {
// won't ever render because the path is down here
return <Route path="/my-route" element={<p>Hello!</p>} />;
};

You can get the same behavior by:

  • Only rendering <Route> elements inside of <Routes>
  • Moving the composition into the element prop
const App = () => (
<div>
<Routes>
<Route path="/my-route" element={<MyRoute />} />
</Routes>
</div>
);

const MyRoute = () => {
return <p>Hello!</p>;
};

How do I nest routes deep in the tree?

In ReactRouter v5 you could render a <Route> or <Switch> anywhere you want. You can keep doing the very same thing, but you need to use <Routes> (<Route> without an 's' will not work). We call these "Descendant <Routes>".

It might have looked like this in ReactRouter v5:

// somewhere up the tree
<Switch>
<Route path="/users" component={Users} />
</Switch>;

// and now deeper in the tree
function Users() {
return (
<div>
<h1>Users</h1>
<Switch>
<Route path="/users/account" component={Account} />
</Switch>
</div>
);
}

In ArchibaldRouter it's almost the same:

  • Note the * in the ancestor routes to get it to match deeper URLs even though it has no direct children
  • You no longer need to know the entire child route path, you can use a relative route now
// somewhere up the tree
<Routes>
<Route path="/users/*" element={<Users />} />
</Routes>;

// and now deeper in the tree
function Users() {
return (
<div>
<h1>Users</h1>
<Routes>
<Route path="account" element={<Account />} />
</Routes>
</div>
);
}

If you had a "floating route" in ReactRouter v5 (not wrapped in a <Switch>), simply wrap it in a <Routes> instead.

// ReactRouter v5
<Route path="/contact" component={Contact} />

// ArchibaldRouter
<Routes>
<Route path="contact" element={<Contact />} />
</Routes>

What Happened to Regexp Routes Paths?

Regexp route paths were removed for two reasons:

  • External dependency + bigger bundle size
  • Non-native support

ArchibaldRouter is using URLPattern Web API that is still marked as experimental. However, we believe that this will be the new standard adopted by all the major browsers. Currently, Safari and Firefox do not support it and for those browsers we have a polyfill enabled.

You can check the following links for more details on how to use it for building URL patterns in your app:

Matching generally static values

A very common route we've seen is a regex matching multiple language codes:

// ReactRouter v5
function App() {
return (
<Switch>
<Route path={/(en|es|fr)/} component={Lang} />
</Switch>
);
}

function Lang({ params }) {
let lang = params[0];
let translations = I81n[lang];
// ...
}

In ArchibaldRouter you can do the following:

// ArchibaldRouter
function App() {
return (
<Routes>
<Route path="/:language(en|es|fr)" element={<Lang />} />
</Routes>
);
}

function Lang() {
const { language } = useParams();
// ...
}

Or you can allow everything to go into a language param and rely on automatic language fix functionality from ArchibaldRouter:

// ArchibaldRouter
function App() {
return (
<Routes>
<Route path="/:language" element={<Lang />} />
</Routes>
);
}

function Lang() {
const { language } = useParams();
// ...
}

Doing some sort of param validation

Another common case was ensuring that parameters were an integer.

// ReactRouter v5
function App() {
return (
<Switch>
<Route path={/users\/(\d+)/} component={User} />
</Switch>
);
}

function User({ params }) {
const id = params[0];
// ...
}

ArchibaldRouter powered by URLPattern allows you to do the following easily:

// ArchibaldRouter
function App() {
return (
<Routes>
<Route path="/users/:userId(\d+)" element={<User />} />
</Routes>
);
}

function User() {
const { userId } = useParams();
// ...
}

Automatic <Route> sorting

You shouldn't be concerned anymore about the order you are defining your <Route> components. ArchibaldRouter will handle it for you!

<Routes>
<Route path="/:language?" element={<Layout />}>
<Route path="*" element={<NotFoundPage />} />
<Route path="c/:categoryId(\d+)" element={<ProductListingPage />} />
<Route index element={<HomePage />} fallback={<TestHomePlaceholder />} />
<Route path=":userId(\d+)" element={<UserPage />} />
<Route path="p">
<Route path="*/secret/path" element={<ProductSecretPage />} />
<Route path=":productId(\d+)" element={<ProductDetailPage />} />
<Route index element={<ProductIndexPage />} />
<Route path="*" element={<ProductNotFoundPage />} />
<Route path="about" element={<ProductAboutPage />} />
</Route>
</Route>
</Routes>

It will be restructured by ArchibaldRouter into the following order:

PositionPatternElement
1"/:language?"<HomePage />
2"/:language?/:userId(\d+)"<UserPage />
3"/:language?/c/:categoryId(\d+)"<ProductListingPage />
4"/:language?/p"<ProductIndexPage />
5"/:language?/p/about"<ProductAboutPage />
6"/:language?/p/:productId(\d+)"<ProductDetailPage />
7"/:language?/p/*/secret/path"<ProductSecretPage />
8"/:language?/p/*"<ProductNotFoundPage />
9"/:language?/*"<NotFoundPage />