Files
turbostarter/.context/turbostarter-framework-context/sections/web/marketing/legal.md
Alejandro Gutiérrez 3527e732d4 feat: turbostarter boilerplate
Production-ready Next.js boilerplate with:
- Runtime env validation (fail-fast on missing vars)
- Feature-gated config (S3, Stripe, email, OAuth)
- Docker + Coolify deployment pipeline
- PostgreSQL + pgvector, MinIO S3, Better Auth
- TypeScript strict mode (no ignoreBuildErrors)
- i18n (en/es), AI modules, billing, monitoring

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:01:55 +01:00

2.9 KiB

title, description, url
title description url
Legal pages Learn how to create and update legal pages /docs/web/marketing/legal

Legal pages

Legal pages are defined in the apps/web/src/app/[locale]/(marketing)/legal directory.

TurboStarter comes with the following legal pages:

  • Terms and Conditions: to define the terms and conditions of your application
  • Privacy Policy: to define the privacy policy of your application
  • Cookie Policy: to define the cookie policy of your application

For obvious reasons, these pages are empty and you need to fill in the content.

Content from CMS

Content for legal pages are stored as MDX files in content collection in packages/cms/src/content/collections/legal directory.

Then it's parsed and rendered as a Next.js page under corresponding slug:

import {
  CollectionType,
  getContentItemBySlug,
  getContentItems,
} from "@turbostarter/cms";

export default async function Page({ params }: PageParams) {
  const item = getContentItemBySlug({
    collection: CollectionType.LEGAL,
    slug: (await params).slug,
    locale: (await params).locale,
  });

  if (!item) {
    return notFound();
  }

  return <Mdx mdx={item.mdx} />;
}

export function generateStaticParams() {
  return getContentItems({ collection: CollectionType.LEGAL }).items.map(
    ({ slug, locale }) => ({
      slug,
      locale,
    }),
  );
}

As it's fully typesafe it also allows us to generate metadata for each page based on the frontmatter that you define in the MDX file:

export async function generateMetadata({ params }: PageParams) {
  const item = getContentItemBySlug({
    collection: CollectionType.LEGAL,
    slug: (await params).slug,
    locale: (await params).locale,
  });

  if (!item) {
    return notFound();
  }

  return getMetadata({
    title: item.title,
    description: item.description,
  })({ params });
}

Read more about it in the CMS section.

ChatGPT prompts

Each .mdx file with legal content include a set of useful prompts that you can use to generate the content.

Please, be aware that **ChatGPT is not a lawyer** and the content generated by it should be reviewed by one before publishing. Take your time and treat the generated content as a starting point not a final document.
---
title: Privacy Policy
description: Our privacy policy outlines how we collect, use, and protect your personal information.
---

{/* 💡 You can use one of the following ChatGPT prompts to generate this 💡 */}

...

Feel free to add your own content or even additional pages to the legal collection.