Slug-based routing

With the introduction of project maps the routing approach using composition slugs is no longer the recommended way of managing URLs in Uniform.

While it's still supported and useful in certain scenarios, Uniform recommends using project maps for routing, linking and URL management.

The slug-based routing solution relies on the "slug" field in a composition that stores either a full URL or a unique pathname. Sometimes the slug of a composition only contains the final path segment of the URL and the full URL is assembled and resolved based on some conventions. For example, a composition of type Product Feature Page would only have my-awesome-shirt as the slug but the full URL would be /products/features/my-awesome-shirt.

Consider the slug-based approach for managing URLs when:

  • You need to fetch specific compositions that aren't attached to a project map node.
  • Another system is responsible for defining and resolving URLs (for example, another CMS or a application framework).
  • Your application has no nested URLs or views.
  • Your compositions only serve non-web channels and don't need URLs.

If every composition has a unique URL slug specified, then use Dynamic Route with optional "Catch all" to cover any slug and the home page.

import { UniformComposition, UniformSlot, } from "@uniformdev/canvas-react"; import { withUniformGetStaticProps, withUniformGetStaticPaths } from '@uniformdev/canvas/slug'; export const getStaticProps = withUniformGetStaticProps({ param: 'slug'}); export const getStaticPaths = withUniformGetStaticPaths(); export default function Page({ data }) { return ( <main> <UniformComposition data={data}> <UniformSlot name="header" /> <UniformSlot name="content" /> <UniformSlot name="footer" /> </UniformComposition> </main> ) }

Alter a list of nodes after fetching and before they're mapped into the paths parameters array. For example, this blacklists some URL patterns because they're covered by dedicated Next.js pages:

import { withUniformGetStaticPaths } from '@uniformdev/canvas-next/slug'; export const getStaticPaths = withUniformGetStaticPaths({ callback: async (compositions) => { const skipSlugs = [ 'mobile-view', // composition only used for mobile app 'internal-test', // some other specified slug not to be generated ]; return compositions.filter((composition) => !skipSlugs.includes(composition.composition._slug)); } });

Alter Props object and composition data.

import { enhance } from '@uniformdev/canvas' import { withUniformGetStaticProps } from '@uniformdev/canvas-next/slug'; import { enhancers } from '../src/lib/enhancers'; export const getServerSideProps = withUniformGetStaticProps({ callback: async (context, composition) => { if (composition) { await enhance({ composition, enhancers, context }); } else { return { notFound: true, } } return { // Enhanced composition data will be injected later, so no need to do it yourself props: { myCustomProp: 'foo', }, // Specifying some NextJS ISG params per page. revalidate: 100, }; } );

A string that you want to strip from the resolved context.resolvedUrl. Useful when calling from a nested folder which isn't part of your slug structure.