Privacy Policy Generator
NDPA 2023-compliant privacy policy generator for websites and applications
Overview
The Privacy Policy Management components provide a comprehensive solution for creating, previewing, and exporting customized, NDPA-compliant privacy policies for your website or application. The system includes three main components: PolicyGenerator, PolicyPreview, and PolicyExporter, which work together to create professional, enterprise-ready privacy policies with variable support.
NDPA Privacy Policy Requirements
Under the NDPA 2023, organizations must maintain a clear and accessible privacy policy that informs data subjects about how their personal data is collected, processed, stored, and protected. The policy must be written in clear, plain language and cover specific elements required by the regulation.
Installation
Install the NDPR Toolkit package which includes the Privacy Policy Generator components:
pnpm add @tantainnovative/ndpr-toolkitComponents
The Privacy Policy Management system includes three main components that work together to create, preview, and export NDPA-compliant privacy policies:
PolicyGenerator
The main component that allows users to create a policy by configuring sections and variables with an intuitive interface.
import { PolicyGenerator } from '@tantainnovative/ndpr-toolkit';
<PolicyGenerator
sections={policySections}
variables={policyVariables}
onGenerate={(policy) => {
// policy.sections - Updated sections
// policy.variables - Updated variables with values
// policy.content - Generated policy content in markdown format
setPolicyContent(policy.content);
}}
title="Privacy Policy Generator"
description="Create your NDPA-compliant privacy policy"
showPreview={true}
allowEditing={true}
/>PolicyPreview
A component for displaying the generated privacy policy with professional formatting and navigation features.
import { PolicyPreview } from '@tantainnovative/ndpr-toolkit';
<PolicyPreview
content={policyContent}
title="Privacy Policy"
showTableOfContents={true}
className="policy-preview"
onContentChange={(updatedContent) => {
setPolicyContent(updatedContent);
}}
/>PolicyExporter
A utility component for exporting the generated policy in various formats (PDF, HTML, Markdown) with professional formatting.
import { PolicyExporter } from '@tantainnovative/ndpr-toolkit';
<PolicyExporter
content={policyContent}
title="Privacy Policy"
filename="privacy-policy"
formats={{
pdf: true,
markdown: true,
html: true
}}
companyInfo={{
name: "Your Company Name",
logo: "/path/to/logo.png",
website: "https://example.com",
email: "privacy@example.com"
}}
/>Variable Support
The Privacy Policy Management system supports variables in templates, allowing for dynamic and enterprise-ready policies. Variables are defined with specific types and can be edited through the PolicyGenerator interface, making it easy to customize the policy for different organizations and use cases.
Defining Variables
Variables are defined as an array of PolicyVariable objects, each with properties like id, name, description, defaultValue, inputType, and required status. These variables can then be referenced in your policy sections using the {{ and }} syntax.
const policyVariables = [
{
id: 'companyName',
name: 'Company Name',
description: 'The legal name of your organization',
defaultValue: 'Your Company',
value: '',
inputType: 'text',
required: true
},
{
id: 'contactEmail',
name: 'Contact Email',
description: 'Email address for privacy inquiries',
defaultValue: 'privacy@example.com',
value: '',
inputType: 'email',
required: true
},
{
id: 'effectiveDate',
name: 'Effective Date',
description: 'When this privacy policy takes effect',
defaultValue: new Date().toISOString().split('T')[0],
value: '',
inputType: 'date',
required: true
},
{
id: 'dataRetentionPeriod',
name: 'Data Retention Period',
description: 'How long you retain user data',
defaultValue: '12 months',
value: '',
inputType: 'text',
required: true
}
];
const policySections = [
{
id: 'introduction',
title: 'Introduction',
template: '# Privacy Policy for {{companyName}}\n\nLast Updated: {{effectiveDate}}\n\n{{companyName}} ("we", "us", or "our") is committed to protecting your privacy.',
required: true,
included: true,
order: 1
}
];Variable Validation
The generatePolicyText utility also provides validation to help you identify missing variables:
// Passing PolicySection[] + OrganizationInfo returns an object with
// fullText, sectionTexts and missingVariables. (Passing a single
// template string instead returns just the substituted string.)
const result = generatePolicyText(policySections, orgInfo);
// The full generated text
console.log(result.fullText);
// Any required OrganizationInfo fields referenced but left empty
console.log(result.missingVariables); // e.g., ['privacyPhone']
// Individual section texts, keyed by section id
console.log(result.sectionTexts);Using with PolicySection Array
import { generatePolicyText, PolicySection } from '@tantainnovative/ndpr-toolkit';
const policySections: PolicySection[] = [
{
id: 'introduction',
title: 'Introduction',
template: '{{name}} ("we", "us", or "our") operates the {{website}} website.',
required: true,
included: true
},
{
id: 'contact',
title: 'Contact Us',
template: 'If you have any questions, please contact us at {{privacyEmail}}.',
required: true,
included: true
}
];
// With PolicySection[], the second argument is an OrganizationInfo object;
// only its keys (name, website, privacyEmail, ...) are substituted.
const orgInfo = {
name: 'Acme Corporation',
website: 'https://acme.com',
privacyEmail: 'privacy@acme.com'
};
const result = generatePolicyText(policySections, orgInfo);
console.log(result.fullText);
console.log(result.sectionTexts.introduction);
console.log(result.sectionTexts.contact);Usage
Here's a complete example of how to implement the Privacy Policy Generator in your application:
import { useState } from 'react';
import {
PolicyGenerator,
PolicyPreview,
PolicyExporter,
} from '@tantainnovative/ndpr-toolkit';
import type { PolicySection, PolicyVariable } from '@tantainnovative/ndpr-toolkit';
const policySections: PolicySection[] = [
{
id: 'introduction',
title: 'Introduction',
template: '{{organizationName}} ("we", "us", or "our") operates the {{websiteUrl}} website.',
required: true,
included: true,
order: 1
},
// More sections...
];
const policyVariables: PolicyVariable[] = [
{
id: 'organizationName',
name: 'Organization Name',
description: 'The legal name of your organization',
defaultValue: 'Your Company',
value: '',
inputType: 'text',
required: true
},
{
id: 'websiteUrl',
name: 'Website URL',
description: 'Your primary website address',
defaultValue: 'https://example.com',
value: '',
inputType: 'url',
required: true
}
];
function PrivacyPolicyPage() {
const [policyContent, setPolicyContent] = useState('');
return (
<div>
<PolicyGenerator
sections={policySections}
variables={policyVariables}
onGenerate={(policy) => {
// policy.sections - PolicySection[] with current values
// policy.variables - PolicyVariable[] with entered values
// policy.content - generated policy content (markdown)
setPolicyContent(policy.content);
}}
title="Privacy Policy Generator"
description="Create your NDPA-compliant privacy policy"
showPreview={true}
allowEditing={true}
/>
{policyContent && (
<div className="mt-6">
<PolicyPreview
content={policyContent}
title="Privacy Policy"
showTableOfContents={true}
onContentChange={setPolicyContent}
/>
<PolicyExporter
content={policyContent}
title="Privacy Policy"
filename="privacy-policy"
formats={{ pdf: true, markdown: true, html: true }}
/>
</div>
)}
</div>
);
}API Reference
PolicyGenerator Props
| Prop | Type | Default | Description |
|---|---|---|---|
| onGenerate | (policy: { sections: PolicySection[]; variables: PolicyVariable[]; content: string }) => void | Required | Callback fired when the policy is generated, receiving the updated sections, variables, and generated content |
| sections | PolicySection[] | DEFAULT_POLICY_SECTIONS | List of policy sections to render and edit |
| variables | PolicyVariable[] | DEFAULT_POLICY_VARIABLES | List of policy variables editable through the interface |
| title | string | "NDPA Privacy Policy Generator" | Title displayed on the generator |
| description | string | NDPA Section 27 default | Description text displayed on the generator |
| generateButtonText | string | "Generate Policy" | Text for the generate button |
| showPreview | boolean | true | Whether to show a preview of the generated policy |
| allowEditing | boolean | true | Whether to allow editing the generated policy content |
| className | string | "" | Custom CSS class for the generator container |
| unstyled | boolean | false | Removes all default styles; use with classNames to apply your own |
generatePolicyText Function
/**
* Generates policy text by replacing variables in a template
*
* @param sectionsOrTemplate - Either an array of PolicySection objects or a template string
* @param organizationInfoOrVariables - Either an OrganizationInfo object or a variables object
* @returns Either a string (if no variables used) or an object with fullText, sectionTexts, and missingVariables
*/
function generatePolicyText(
sectionsOrTemplate: PolicySection[] | string,
organizationInfoOrVariables: OrganizationInfo | Record<string, string>
): string | {
fullText: string;
sectionTexts: Record<string, string>;
missingVariables: string[];
}PolicyTemplate Type
interface PolicyTemplate {
id: string;
name: string;
description: string;
organizationType: 'business' | 'nonprofit' | 'government' | 'educational';
sections: PolicySection[];
variables: Record<string, {
name: string;
description: string;
required: boolean;
defaultValue?: string;
}>;
version: string;
lastUpdated: number;
ndpaCompliant: boolean;
}PolicySection Type
interface PolicySection {
id: string;
title: string;
/** Template text for the section (supports {{variable}} tokens) */
template: string;
/** Whether the section is required by the NDPA */
required: boolean;
/** Whether the section is included in the generated policy */
included: boolean;
description?: string;
order?: number;
/** Variables that can be used in the section template */
variables?: string[];
}PolicyVariable Type
interface PolicyVariable {
id: string;
/** Name of the variable as it appears in the template */
name: string;
description: string;
defaultValue?: string;
/** Current value of the variable */
value: string;
inputType: 'text' | 'textarea' | 'email' | 'url' | 'date' | 'select';
/** Options for select inputs */
options?: string[];
required: boolean;
}OrganizationInfo Type
interface OrganizationInfo {
name: string;
website: string;
/** Contact email for privacy inquiries */
privacyEmail: string;
address?: string;
privacyPhone?: string;
dpoName?: string;
dpoEmail?: string;
industry?: string;
/** NDPC registration number (if registered) */
ndpcRegistrationNumber?: string;
}PolicyPage — drop-in renderer
<PolicyPage /> (added in v3.4.0) renders a fully-styled privacy policy from a typed PrivacyPolicy object. Pair it with useDefaultPrivacyPolicy for a zero-config compliance page:
// app/privacy/page.tsx
'use client';
import { useDefaultPrivacyPolicy } from '@tantainnovative/ndpr-toolkit';
import { PolicyPage } from '@tantainnovative/ndpr-toolkit/policy';
export default function PrivacyPage() {
const { policy } = useDefaultPrivacyPolicy({
orgInfo: {
name: 'Acme Nigeria Ltd',
email: 'privacy@acme.ng',
website: 'https://acme.ng',
address: '12 Marina, Lagos',
},
});
return policy ? <PolicyPage policy={policy} /> : null;
}Render mode: shadow vs inline
| mode | Renders | SEO | Host CSS isolation | Best for |
|---|---|---|---|---|
'shadow' (default) | Inside Shadow DOM, opinionated styles included | ❌ | ✅ structural | In-app embeds — drop-in widget |
'inline' | Directly in host doc body | ✅ | ⚠️ consumer styles | SSR'd /privacy pages, public legal pages |
Inline mode + typography pairing
Inline mode defaults includeStyles: falseso bare element selectors don't leak. Pair with your own typography library:
// 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 (target the data attribute)
[data-ndpr-component="policy-page"] article {
font-family: Georgia, serif;
line-height: 1.7;
}Theme: light / dark / auto
Theme defaults to 'light' (added in v3.4.1). Shadow DOM does not isolate prefers-color-scheme, so before 3.4.1 every visitor on macOS dark mode saw a dark policy bleed through any light-only host. Default light is safer for embedded widgets — opt in to OS-driven theming when you actively want it:
// Default — no prefers-color-scheme: dark block emitted.
<PolicyPage policy={policy} />
// Force dark.
<PolicyPage policy={policy} options={{ theme: 'dark' }} />
// Follow OS preference.
<PolicyPage policy={policy} options={{ theme: 'auto' }} />TOC anchor links work in Shadow DOM
The exported policy includes a table-of-contents nav with intra-document anchors. Browser default anchor behaviour can't traverse Shadow DOM boundaries, so as of v3.5.1 PolicyPage installs a click delegate on the shadow root that intercepts these clicks and scrolls the matching <section> into view. No consumer code required.
Custom CSS injection
// Brand without leaving shadow mode.
<PolicyPage
policy={policy}
options={{
customCSS: ':root { --color-accent: #1d4ed8; --max-width: 64rem; }',
}}
/>Best Practices
- Clear Language: Ensure your privacy policy is written in clear, plain language that is easy for data subjects to understand.
- Regular Updates: Review and update your privacy policy regularly, especially when there are changes to your data processing activities.
- Accessibility: Make your privacy policy easily accessible on your website or application, typically through a link in the footer.
- Customization: While the generator provides a solid template, customize the policy to accurately reflect your specific data practices.
- Legal Review: Have your generated privacy policy reviewed by a legal professional familiar with the NDPA to ensure compliance.
- Use Variables: Leverage the variable system to create reusable templates that can be easily updated when your organization information changes.
Need Help?
If you have questions about implementing the Privacy Policy Generator or need assistance with NDPA compliance, check out these resources: