> ## Documentation Index
> Fetch the complete documentation index at: https://docs.makeswift.com/llms.txt
> Use this file to discover all available pages before exploring further.

# <Page>

> The `<Page>` component takes a Makeswift snapshot and renders React elements using [components registered](/developer/reference/runtime/register-component) with the runtime.

## Props

<ParamField query="snapshot" type="Snapshot" required>
  The Makeswift snapshot to render.
</ParamField>

<ParamField query="metadata" type="boolean | PageMetadataSettings" default="true">
  Controls which page metadata tags from Makeswift are rendered in the `<head>` of the page. More on this in the [Rendering metadata](#rendering-metadata) section below.
</ParamField>

## Example

### App Router

The following example sets up a [catch all dynamic route](https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes#optional-catch-all-segments) in the app router under `[[...path]]/page.tsx`.

```tsx src/app/[[...path]]/page.tsx theme={null}
import { getSiteVersion } from "@makeswift/runtime/next/server";
import { notFound } from "next/navigation";
import { Page as MakeswiftPage } from "@makeswift/runtime/next";

import { client } from "@/makeswift/client";

export async function generateStaticParams() {
  const pages = await client.getPages().toArray();

  return pages.map((page) => ({
    path: page.path.split("/").filter((segment) => segment !== ""),
  }));
}

export default async function Page({
  params,
}: {
  params: Promise<{ path?: string[] }>;
}) {
  const path = "/" + ((await params)?.path ?? []).join("/");
  const snapshot = await client.getPageSnapshot(path, {
    siteVersion: getSiteVersion(),
  });

  if (snapshot == null) return notFound();

  return <MakeswiftPage snapshot={snapshot} />;
}
```

### Pages Router

The following example sets up a [catch all dynamic route](https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes#optional-catch-all-segments) in the pages router under `[[...path]].tsx`.

<CodeGroup>
  ```tsx src/pages/[[...path]].tsx theme={null}
  import {
    GetStaticPathsResult,
    GetStaticPropsContext,
    GetStaticPropsResult,
  } from "next";

  import {
    Page as MakeswiftPage,
    PageProps as MakeswiftPageProps,
    Makeswift,
    type SiteVersion
  } from "@makeswift/runtime/next";

  import { client } from "@/makeswift/client";
  import "@/makeswift/components";

  type ParsedUrlQuery = { path?: string[] };

  export async function getStaticPaths(): Promise<
    GetStaticPathsResult<ParsedUrlQuery>
  > {
    const pages = await client.getPages().toArray();

    return {
      paths: pages.map((page) => ({
        params: {
          path: page.path.split("/").filter((segment) => segment !== ""),
        },
      })),
      fallback: "blocking",
    };
  }

  export type PageProps = MakeswiftPageProps & {
    siteVersion: SiteVersion | null;
  };

  export async function getStaticProps({
    params,
    previewData,
  }: GetStaticPropsContext<ParsedUrlQuery>): Promise<
    GetStaticPropsResult<PageProps>
  > {
    const path = "/" + (params?.path ?? []).join("/");
    const siteVersion = Makeswift.getSiteVersion(previewData);
    const snapshot = await client.getPageSnapshot(path, {
      siteVersion,
    });

    if (snapshot == null) return { notFound: true };

    return {
      props: {
        snapshot,
        siteVersion,
      },
    };
  }

  export default function Page({ snapshot }: MakeswiftPageProps) {
    return <MakeswiftPage snapshot={snapshot} />;
  }
  ```
</CodeGroup>

### Rendering metadata

By default, the `<Page>` component will render metadata tags in the `<head>` of your page with data provided in the Visual Builder, such as the page title, description, social image, etc. If you have other sources
of truth for your page metadata, you can avoid collisions with Makeswift by controlling which fields are rendered with the `metadata` prop. By default, all metadata from Makeswift is rendered.

You can pass a boolean to disable or enable all metadata fields. By passing `false`, you can disable all Makeswift metadata fields from being rendered. This implies that you will manually handle rendering metadata on your own.

```tsx theme={null}
// Disable all Makeswift metadata fields
<Page snapshot={snapshot} metadata={false} />
```

For more granular control, you can pass a `PageMetadataSettings` object to specify which metadata fields should be rendered. Each property is a boolean that indicates whether to render that specific metadata field.

```ts theme={null}
type PageMetadataSettings = {
  title?: boolean;
  description?: boolean;
  keywords?: boolean;
  socialImage?: boolean;
  canonicalUrl?: boolean;
  indexingBlocked?: boolean;
  favicon?: boolean;
};
```

Additionally, omitting a field will result in it not being rendered. For example, to only render the `title` and `description` data from Makeswift use the following:

```tsx theme={null}
<Page snapshot={snapshot} metadata={{ title: true, description: true }} />
```

## Changelog

| Version                                                                                          | Changes                     |
| ------------------------------------------------------------------------------------------------ | --------------------------- |
| [`v0.23.3`](https://github.com/makeswift/makeswift/releases/tag/%40makeswift%2Fruntime%400.23.3) | Added `metadata` prop       |
| [`v0.0.1`](https://github.com/makeswift/makeswift/releases/tag/%40makeswift%2Fruntime%400.0.1)   | Released `<Page>` component |
