PolicyPage
Renders a typed PrivacyPolicy object as a full document — either inside a Shadow DOM root (default, opinionated styling) or inline in the host document (SSR-safe, your own typography).
Overview
PolicyPage is the renderer for the typed PrivacyPolicyobjects produced by AdaptivePolicyWizard, PolicyGenerator, or your own code. It delegates HTML generation to exportHTML(policy, options) under the hood, so the exported document and the rendered page are byte-for-byte identical.
Two render modes are available, each tuned for a different surface:
- Shadow mode (default) — mounts the policy inside a Shadow DOM root, fully isolating the embedded
<style>block. Use this for in-app embeds where you want the rich, opinionated default styling without polluting global CSS. Client-only. - Inline mode — injects the policy markup directly into the host document. Defaults to
includeStyles: falseso bare element selectors don't leak. Pair with your own CSS / design tokens. SSR-safe.
Exported from the /policy subpath:
import { PolicyPage } from '@tantainnovative/ndpr-toolkit/policy';Quickstart
import { PolicyPage } from '@tantainnovative/ndpr-toolkit/policy';
import type { PrivacyPolicy } from '@tantainnovative/ndpr-toolkit';
export default function PrivacyRoute({ policy }: { policy: PrivacyPolicy }) {
// Inline mode — crawlable markup, you supply the typography
return (
<article className="prose prose-slate dark:prose-invert max-w-3xl mx-auto">
<PolicyPage policy={policy} mode="inline" />
</article>
);
}Choosing a mode
| Mode | Renders | SEO | Host-CSS isolation | Best for |
|---|---|---|---|---|
'shadow' (default) | Inside a Shadow DOM root, opinionated styles included | Markup is invisible to crawlers | Structurally impossible to leak | In-app embeds where you want a polished drop-in widget |
'inline' | Directly in the host document body | Crawlable markup | Consumer styles the markup themselves | SSR'd /privacy pages, public legal pages |
Props
| Prop | Type | Description |
|---|---|---|
policy | PrivacyPolicy | Required. The typed policy object — usually obtained from the wizard's onComplete or your own builder. |
mode | 'shadow' | 'inline' | Render mode. Defaults to 'shadow'. |
className | string | Class applied to the wrapping <div> (the shadow host in shadow mode, the inline container otherwise). |
options | HTMLExportOptions | Pass-through to exportHTML. Toggle includeStyles, includePrintCSS, inject customCSS, or pick a theme ('light' / 'dark' / 'auto'). Defaults differ by mode: shadow includes styles; inline omits them. |
Inline-mode typography
The rendered markup is plain semantic HTML — <article>, <section>, <h2>, <p>, <ul>. Pair it with your own typography:
// Tailwind + @tailwindcss/typography
<article className="prose prose-slate dark:prose-invert max-w-3xl mx-auto">
<PolicyPage policy={policy} mode="inline" />
</article>
// shadcn/ui card
<Card>
<CardContent className="prose dark:prose-invert">
<PolicyPage policy={policy} mode="inline" />
</CardContent>
</Card>
// Raw CSS
// .ndpr-policy-page article { font-family: Georgia, serif; line-height: 1.7; }
// .ndpr-policy-page h2 { font-size: 1.5rem; margin-top: 2rem; }Branding shadow mode
Stay in shadow mode and brand the policy by passing theme and customCSS through options:
<PolicyPage
policy={policy}
options={{
theme: 'auto', // 'light' (default) | 'dark' | 'auto'
customCSS: ':root { --color-accent: #1d4ed8; --max-width: 64rem; }',
}}
/>