Overview
When developing with Abyss, we highly recommend utilizing React Router to handle routing within your application. Many useful Abyss components, such as Link and Breadcrumbs, are integrated seamlessly with version 7 and above of react-router. You can find examples of how to establish routing within your application using our collection of Abyss routing components and tools in the following sections.
Although it is technically possible to use NextJS page and app routing, this is not recommended for best results.
Laying the foundation
To start off, wrap the base of your application with the RouterProvider to enable react-router navigation.
Next up is generating a browser router which contains all the routes and enables client side routing for your web application. The Abyss createRouter tool can assist with this; import createRouter and provide it your Routes component which will hold all the individual routes for your application (more on this in the next section - Creating Routes). createRouter will return a router that should then be passed into the RouterProvider.
import { RouterProvider } from '@uhg-abyss/web/ui/RouterProvider';import { createRouter } from '@uhg-abyss/web/tools/createRouter';
const router = createRouter(Routes);
export const App = ({ children }) => { return <RouterProvider router={router}>{children}</RouterProvider>;};Creating routes
Before using routes in an application, they need to be defined, which is typically done within a component name, Routes. Into this newly created Routes component, begin by importing the Router component along with any page components you want to associate with a particular route. Next, add a single instance of Router.Routes, then define individual routes using Router.Route (leverages react-router Route). Whenever the URL changes, react-router will reference the path value defined within your Router.Route components to find a match. If a match is found, react-router will render the associated component within the element prop.
import React from 'react';import { Router } from '@uhg-abyss/web/ui/Router';import { Home } from './Home';import { Albums } from './Album';
export const Routes = () => { return ( <Router.Routes> <Router.Route path="/" element={<Home />} /> <Router.Route path="/albums" element={<Albums />} /> </Router.Routes> );};Dynamic routing
Dynamic segments are parts of the URL path that start with ":". When the route matches the URL, dynamic segments are parsed from it and provided as params to other router APIs. In this example, any values after "/album/:" in the URL will be supplied to params.albumId. More information on accessing these parameters can be found in the next section, Routing with Parameters.
import React from 'react';import { Router } from '@uhg-abyss/web/ui/Router';import { Home } from './Home';import { Albums } from './Album';
export const Routes = () => { return ( <Router.Routes> <Router.Route path="/" element={<Home />} /> <Router.Route path="/albums" element={<Albums />} /> <Route.Route path="/albums/:albumId" element={<Album />} /> </Router.Routes> );};Routing with parameters
To access route params you'll need to first import useRouter. useRouter provides several methods that allow users to manage and interact with routing and navigation, including getRouteParams. When getRouteParams is called, it returns an object of key/value pairs of the dynamic params available from the current URL.
import React from 'react';import { useRouter } from '@uhg-abyss/web/hooks/useRouter';
const Album = () => { const { getRouteParams } = useRouter(); const { albumId } = getRouteParams();
console.log(albumId); // "thriller"};Nested routing
Nested routing couples segments of the URL to component hierarchy and data. In this example, we have a parent route with the path of "artist" wrapping two child routes, with a path of "albums" and "about". When the URL path matches "/artist/albums" or "/artist/about", the components associated with these child routes are rendered within the Artist component using Router.Outlet (leverages react-router Outlet).
import React from 'react';import { Router } from '@uhg-abyss/web/ui/Router';import { Artist } from './Artist';import { Albums } from './Albums';import { About } from './About';
export const Routes = () => { return ( <Router.Routes> <Router.Route path="artist" element={<Artist />}> <Router.Route path="albums" element={<Albums />} /> <Router.Route path="about" element={<About />} /> </Router.Route> </Router.Routes> );};Utilize Router.Outlet in order to render the components from the matching child routes.
import React from 'react';import { Router } from '@uhg-abyss/web/ui/Router';
export const Artist = () => { return ( <> <h1>Artist Page</h1> <Router.Outlet /> // If the path matches "/artist/albums", the Albums component will be rendered; if it matches "/artist/about", the About component will be rendered. </> );};