Pages and sections

Use a small set of composable containers rather than a separate page format for every layout.

Building blockResponsibility
PageShellOptional shared theme and explicit color mode. Renders a div, not a page landmark.
NavigationSite-level menu and optional satellites, independently of the page.
ContentPageMain landmark, title, introduction, breadcrumbs and section registry.
SectionA meaningful content region with an anchor, navigation label and optional visible heading.
ContentGridColumn layout for explicit ContentBlocks.
ContentBlockResponsive column span; no automatic heading or registration.
SectionsRender an array of serializable section models.
svelte
<script>
  import {
    PageShell,
    Navigation,
    MainMenu,
    ContentPage,
    Section
  } from '@page-sections/svelte';
</script>

<PageShell>
  <Navigation>
    {#snippet menu()}<MainMenu
        items={[{ id: 'home', label: 'Home', href: '/' }]}
      />{/snippet}
  </Navigation>
  <ContentPage page={{ title: 'A simple page' }}>
    <Section section={{ id: 'intro', title: 'Introduction', headline: 'Welcome' }}>
      <p>Your content stays normal Svelte markup.</p>
    </Section>
  </ContentPage>
</PageShell>

ContentPage does not own the main menu or interpret a page.sections array. Put Navigation alongside it and render children or a Sections component explicitly. Avoid nesting ContentPages: each renders a main landmark and page heading.

Sections can be standalone. Within a ContentPage their anchors must be unique and match ^[a-z][a-z0-9-]*$; registration rejects blank labels and duplicates. Prefer these conventions outside a page as well.

Use declarative markup when content is authored in Svelte. Use data-driven Sections for CMS content, and provide custom renderers for domain-specific structures. Both paths use the same components and models.

Continue with ContentPage and PageShell, Section and ContentGrid, and Data Models and Custom Sections.