Next.js routing
Static and dynamic routing with Next.js
✔️ Static routing with next.js is pretty simple given that the app routes hierarchy will exactly mirror the contents of the /pages
folder on the server, be it in development mode or at build time. For example, if a user agent requests /some/content
:
- If the
/pages/some/content.jsx
file exists, the request is served. - If it doesn't exist, the server responds with a HTTP 404 error.
✔️ The next.js pre-rendering features cover 2 uses cases when it comes to dynamic content generation :
- Pages contents depend on external data (use case for
getStaticProps
andgetServerSideProps
). - Pages paths depend on external data, for instance the site hierarchy depends on file system reads or database queries.
- The latest is the typical use case for
getStaticPaths
, which enables dynamic routing in a next.js app. -
getStaticPaths
behaves exactly likegetStaticProps
: it runs at every request in development mode, then runs only once at build time.
✔️ Dynamic routing is enabled in next.js through the use of dynamic segments - this concept can be thought of as :
- Allow the use of wildcards in the supported server routes by enclosing route segments in brackets :
/dynamic/[path]
. - Have the server dynamically generate a route when hit with a request that matches a route with dynamic segments.
- Serve the request using bracket-enclosed pages in the
/pages
folder hierarchy :/pages/dynamic/[path].jsx
.
✔️ Dynamic routes generation
- If a page has to support dynamic routing (ie. it serves requests for routes w/ dynamic segments) it has to export
getStaticPaths
- For instance, in
/pages/dynamic/[path].jsx
:
const
// async retrieval of ids to populate the
// list of pages to statically generate
getStaticPaths = () => ({
// all routes defined here will be statically generated and
// handled by the current page - the list must include a
// specific route for each possible value of the dynamic segment
// if the dynamic segment value is not in this list -> 404
paths: [
// matches /dynamic/pageone
params: {path: `pageone`},
// matches /dynamic/pagetwo
params: {path: `pagetwo`},
// matches /dynamic/pagethree
params: {path: `pagethree`}
],
// this is the value to set when using next for SSG - the other
// possible values (`true` and `blocking`) are only relevant in
// the context of an SSR capable app for which a small subset of
// routes are to be statically generated at build time and other
// routes are meant to be generated on demand
fallback: false
// essentially, this value tells how to run getStaticProps when
// 1 - the app receives a request for a dynamic route.
// 2 - the route for the dynamic segment value was not exported
// by getStaticPaths thus not generated at build time.
});
// export static paths generation function in a namespace
export {getStaticPaths};
- The
params
object matching the requested dynamic route will be passed to the page'sgetStaticProps
export :
// async retrieval of props for static site generation
getStaticProps = async context => {
const
// read dynamic route segments values from context
{params: {path}} = context;
// use the segments values to retrieve relevant data ...
// and pass it as props to the page for rendering
return {props: {relevantData}};
};
✔️ Catch-all segments
- Catch-all segments are a specific types of dynamic segments that will match all subsequent segments of a dynamic route.
- As a result, the dynamic segments values in the
getStaticPaths
export can be arrays :
const
// ...
getStaticPaths = () => ({
// ...
paths: [
// matches /dynamic/page/one
params: {path: [ `page`, `one` ]}
// matches /dynamic/page/two
params: {path: [ `page`, `two` ]}
// ...
],
// ...
});
// export static paths generation function in a namespace
export {getStaticPaths};
- To use catch-all segments for dynamic routing in a page, add an ellipsis inside the brackets :
/pages/dynamic/[...path].jsx
.