Docs
Next

Build layout and pages

Configure the shared Header and Footer, then publish pages through SysthemaPage.

On this page

GoalLink to this section

Create shared navigation and publish the home, services, about, contact and privacy pages. Use the starter's CMS route and default page template first.

1. Keep shared chrome in the site templateLink to this section

The starter uses RootLayout, RootHeader and RootFooter. The latter two render the Header and Footer globals with Systhema's components. Replace the logo and configure their content in Admin.

This replacement preserves the starter's responsive menu controls. For a localized site, make the same edits in shell.tsx and pass its route locale to RootLayout; do not force English.

src/app/(site)/template.tsx
import type { ReactNode } from 'react'
import { Geist } from 'next/font/google'
import configPromise from '@payload-config'
import { getPayload } from 'payload'
import { RootLayout, RootHeader, RootFooter } from '@systhemaui/payload/next'
import './globals.css'

const geist = Geist({ subsets: ['latin'], weight: ['400', '700'] })

function Logo() {
  return <span>Northline</span>
}

export default function SiteTemplate({ children }: { children: ReactNode }) {
  const payloadInstance = getPayload({ config: configPromise })

  return (
    <RootLayout
      className={geist.className}
      htmlAttributes={{ lang: 'en' }}
      payloadInstance={payloadInstance}
    >
      <RootHeader
        payloadInstance={payloadInstance}
        position="sticky"
        logo={<Logo />}
        elementProps={{
          headerNavigationItem: { className: 'max-lg:hidden' },
          headerMenuToggle: { className: 'lg:hidden' },
          headerCta: { className: 'max-lg:hidden' },
          menu: { className: 'lg:hidden' },
          menuBackdrop: { className: 'lg:hidden' },
        }}
      />
      {children}
      <RootFooter payloadInstance={payloadInstance} logo={<Logo />} />
    </RootLayout>
  )
}

See Header, Footer and Header and Footer content.

2. Create the CMS pagesLink to this section

In Admin, create Home, Services, About, Contact and Privacy in Pages. Add a Cookie Policy page if the site requires one. Use the default template. Select the home page in General Settings. Build navigation using internal page references so routing can resolve the correct paths.

Publish each page after adding a title and initial content. Draft pages are for preview; verify published URLs while signed out.

3. Let SysthemaPage own CMS routingLink to this section

The managed catch-all already imports and renders this API:

Managed CMS catch-all, shown for reference
import configPromise from '@payload-config'
import { getPayload } from 'payload'
import { SysthemaPage } from '@systhemaui/payload/next'

export default async function Page({
  params,
  searchParams,
}: {
  params: Promise<{ segments?: string[] }>
  searchParams: Promise<Record<string, string | string[] | undefined>>
}) {
  return (
    <SysthemaPage
      params={params}
      searchParams={searchParams}
      payloadInstance={getPayload({ config: configPromise })}
    />
  )
}

Do not replace that route to implement a custom CMS page. Register a page template instead. SysthemaPage resolves the page, chooses its template and connects live preview. The catch-all's separate generateMetadata export calls generateSysthemaMetadata; retain it. See Frontend rendering.

The default template owns <main id="main-content"> and <Article>. Its root content field accepts section-level blocks. Do not add another main or Article inside those blocks.

4. Add a code-owned route only when neededLink to this section

A route outside (systhema) can serve a page whose content is genuinely code-owned:

src/app/(site)/status/page.tsx
import { Article, Section, Heading, Paragraph } from '@systhemaui/next'

export default function StatusPage() {
  return (
    <main id="main-content">
      <Article theme="default" layoutBackground="main">
        <Section>
          <Heading.h1>Service status</Heading.h1>
          <Paragraph>Contact the office for current service availability.</Paragraph>
        </Section>
      </Article>
    </main>
  )
}

Choose route names that do not hide intended CMS pages. Use a custom page template when editors need to control the content.

Check your workLink to this section

  • The logo, desktop navigation and mobile menu work.
  • The skip link lands on main-content.
  • Published pages load while signed out, including nested paths.
  • Footer links point to the right pages.

Next: Choose the content model.