OpenPolicy
React

React

Render policies as headless React components with @openpolicy/react

@openpolicy/react provides headless React components that compile and render policies at runtime — no build step, no generated files. This is "framework mode": your policy config lives in TypeScript and renders directly as React.

Installation

bun add @openpolicy/react @openpolicy/sdk

Create your config

Create an openpolicy.ts at the root of your project using defineConfig() from @openpolicy/sdk:

// openpolicy.ts
import { defineConfig } from "@openpolicy/sdk";

export default defineConfig({
  company: {
    name: "Acme Inc.",
    legalName: "Acme Corporation",
    address: "123 Main St, Springfield, USA",
    contact: "privacy@acme.com",
  },
  privacy: {
    effectiveDate: "2026-01-01",
    dataCollected: {
      "Account Information": ["Name", "Email address"],
      "Usage Data": ["Pages visited", "Browser type", "IP address"],
    },
    legalBasis: "Legitimate interests and consent",
    retention: { "Account data": "Until account deletion" },
    cookies: { essential: true, analytics: false, marketing: false },
    thirdParties: [],
    userRights: ["access", "erasure"],
    jurisdictions: ["us", "eu"],
  },
  terms: {
    effectiveDate: "2026-01-01",
    acceptance: { methods: ["using the service", "creating an account"] },
    governingLaw: { jurisdiction: "Delaware, USA" },
  },
});

See the openpolicy.ts reference → for all available fields.

OpenPolicy provider

Wrap your app (or just the policy pages) with <OpenPolicy config={...}>. The provider:

  • Sets the policy config in React context so all child components can access it
  • Automatically injects default styles via a <style> tag (React 19 style hoisting)
import { OpenPolicy } from "@openpolicy/react";
import openpolicy from "./openpolicy";

export function App() {
  return (
    <OpenPolicy config={openpolicy}>
      {/* policy components go here */}
    </OpenPolicy>
  );
}

Components

Three components cover all policy types. Each reads from the nearest <OpenPolicy> provider by default, or accepts a config prop to override it.

<PrivacyPolicy />

import { OpenPolicy, PrivacyPolicy } from "@openpolicy/react";
import openpolicy from "./openpolicy";

export function PrivacyPolicyPage() {
  return (
    <OpenPolicy config={openpolicy}>
      <PrivacyPolicy />
    </OpenPolicy>
  );
}

<TermsOfService />

import { OpenPolicy, TermsOfService } from "@openpolicy/react";
import openpolicy from "./openpolicy";

export function TermsPage() {
  return (
    <OpenPolicy config={openpolicy}>
      <TermsOfService />
    </OpenPolicy>
  );
}

<CookiePolicy />

import { CookiePolicy, OpenPolicy } from "@openpolicy/react";
import openpolicy from "./openpolicy";

export function CookiePolicyPage() {
  return (
    <OpenPolicy config={openpolicy}>
      <CookiePolicy />
    </OpenPolicy>
  );
}

Props

All three components accept the same optional props:

PropTypeDescription
configOpenPolicyConfig | PrivacyPolicyConfigOverride the provider config for this component
componentsPolicyComponentsCustom React components for each node type
styleCSSPropertiesInline styles applied to the root wrapper element

Without a provider

Each component can also be used standalone by passing config directly — no provider needed:

import { PrivacyPolicy } from "@openpolicy/react";
import openpolicy from "./openpolicy";

export function PrivacyPolicyPage() {
  return <PrivacyPolicy config={openpolicy} />;
}

Note: when used without a provider, default styles are not injected automatically. You can add them manually or use the style prop, or see Styling → for other approaches.

On this page