Global header and footer
Developer preview
Goal: show the same header and footer on each page. Authors edit the header and the footer one time, in their own compositions. Each page then shows the new version.
Prerequisites#
- A Next.js app with the SDK. Refer to Next.js App Router SDK.
- The
app/uniform/[code]/page.tsxroute and thecomponents/resolveComponent.tsxfile.
Step 1: Make the compositions in Uniform#
- Make a component definition
globalHeaderwith a text parametersiteNameand a slotnavigation. - Make a component definition
globalFooterwith a text parametercopyrightand a slotlinks. - Make a composition of the type
globalHeader. Set its slug toglobal-header. - Make a composition of the type
globalFooter. Set its slug toglobal-footer. - Publish the two compositions.
The two compositions do not need a project map node. The page gets them by their slug.
Step 2: Make the header and footer components#
components/global-header.tsx
components/global-footer.tsx
For the link components in the slots, refer to Links.
Step 3: Register the components#
Add the two components to the component map:
components/resolveComponent.tsx
Step 4: Resolve and render the three compositions#
Replace UniformComposition in the page. Get the three compositions at the same time with Promise.all. Then render them in one UniformContext:
app/uniform/[code]/page.tsx
If you use Cache Components, import resolveRouteFromCode and resolveCompositionBySlug from @uniformdev/next-app-router/cache. The rest of the code stays the same. Refer to Caching.
How it works#
- The same page state: each resolver gets the same
code. Thus the header and the footer use the state, the locale and the release of the page. In Canvas preview, they show the draft version. Visitors see the published version. - A missing composition: if Uniform has no composition for a slug, the resolver returns
route: undefined. ThenUniformResolvedCompositionrenders nothing, and the page still renders.requireCompositionis only on the page composition. Thus only a missing page gives a 404. - Personalization: the header and the footer can have personalizations and A/B tests. The SDK renders them the same as in the page composition.
Why one UniformContext#
UniformContext does these tasks for the full page:
- It starts the Uniform Context in the browser with the data of one composition. Give it the page composition.
- It adds the visual editing script in draft and editor states.
- In edge mode, it adds the script that the edge middleware fills with the visitor state.
A second UniformContext adds these scripts a second time. The browser uses only the first Context, so the second Context does no useful work. Thus render UniformContext one time, and put all UniformResolvedComposition elements in it. Refer to Render more than one composition.
How the header and footer stay up to date#
A published composition that you get by slug has two cache tags:
| Tag | Example |
|---|---|
composition-slug:<slug> | composition-slug:global-header |
composition:<id> | composition:6c4f… |
When an author publishes the header, Uniform sends the composition.published webhook. The webhook handler in app/api/preview/route.ts revalidates these tags with the "max" profile. Next.js then marks the cached pages as stale. The next request to a page gets the old page and starts a new render in the background. The request after it gets the new header. Refer to Caching.
warning
Do not put the header in app/layout.tsx with its own UniformContext. A page then has two UniformContext elements. Resolve and render all compositions of the page in the page file.