appclerk-react

React components and hooks for AppClerk compliance infrastructure. Works with Next.js, Vite, CRA, and other React 18+ frameworks.

📦 npm: appclerk-react•📄 License: MIT•View on npm →

Installation

npm install appclerk-core appclerk-react
# or
yarn add appclerk-core appclerk-react
# or
pnpm add appclerk-core appclerk-react

Quick Start

In the App Router, create a small "use client" wrapper for AppClerkProvider, then wrap your app with it.

// app/appclerk-provider.tsx
"use client";

import { AppClerkProvider } from "appclerk-react";

export function AppClerkRootProvider({ children }: { children: React.ReactNode }) {
  return (
    <AppClerkProvider
      apiKey={process.env.NEXT_PUBLIC_APPCLERK_API_KEY!}
      projectId={process.env.NEXT_PUBLIC_APPCLERK_PROJECT_ID!}
    >
      {children}
    </AppClerkProvider>
  );
}
// app/layout.tsx
import type { Metadata } from "next";
import "./globals.css";
import { AppClerkRootProvider } from "./appclerk-provider";

export const metadata: Metadata = { /* ... */ };

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <AppClerkRootProvider>{children}</AppClerkRootProvider>
      </body>
    </html>
  );
}

Provider Setup

Next.js (Pages Router)

// pages/_app.tsx
import { AppClerkProvider } from "appclerk-react";

export default function App({ Component, pageProps }) {
  return (
    <AppClerkProvider
      apiKey={process.env.NEXT_PUBLIC_APPCLERK_API_KEY}
      projectId={process.env.NEXT_PUBLIC_APPCLERK_PROJECT_ID}
    >
      <Component {...pageProps} />
    </AppClerkProvider>
  );
}

Vite / Create React App

// src/main.tsx or src/index.tsx
import { AppClerkProvider } from "appclerk-react";
import { createRoot } from "react-dom/client";
import App from "./App";

const root = createRoot(document.getElementById("root")!);

root.render(
  <AppClerkProvider
    apiKey={import.meta.env.VITE_APPCLERK_API_KEY}
    projectId={import.meta.env.VITE_APPCLERK_PROJECT_ID}
  >
    <App />
  </AppClerkProvider>
);

Components

PrivacyPolicy

Display your privacy policy as a native markdown view or embed via webview.

"use client";
import { PrivacyPolicy } from "appclerk-react";

export function MyPrivacyPolicy() {
  return <PrivacyPolicy renderMode="native" displayMode="inline" />;
}

TermsOfService

Display your terms of service document, inline or in a modal.

"use client";
import { TermsOfService } from "appclerk-react";

export function MyTerms() {
  return <TermsOfService renderMode="native" displayMode="modal" />;
}

ComplianceStatus

Show a detailed compliance status panel, including score and issues.

"use client";
import { ComplianceStatus } from "appclerk-react";

export function CompliancePanel() {
  return <ComplianceStatus />;
}

Style Guide

AppClerk React SDK provides comprehensive styling options for all markdown elements. You can style every aspect of your legal documents using either CSS classes or inline styles.

Container Styling

Use the className prop to style the document container:

<TermsOfService className="max-w-4xl mx-auto p-6 bg-white rounded-lg shadow-lg" />

CSS Classes (markdownClassNames)

Apply CSS classes to specific markdown elements using the markdownClassNames prop. Ideal when using CSS frameworks like Tailwind CSS:

<TermsOfService
	markdownClassNames={{
		container: "max-w-4xl mx-auto",
		h1: "text-3xl font-bold text-gray-900 mb-4",
		h2: "text-2xl font-semibold text-gray-800 mt-8 mb-3",
		h3: "text-xl font-medium text-gray-700 mt-6 mb-2",
		p: "text-gray-700 mb-4 leading-relaxed",
		ul: "list-disc ml-6 mb-4 space-y-2",
		ol: "list-decimal ml-6 mb-4 space-y-2",
		li: "text-gray-700 mb-2",
		a: "text-blue-600 hover:text-blue-800 underline",
		strong: "font-semibold text-gray-900",
		em: "italic text-gray-700",
		code: "bg-gray-100 px-2 py-1 rounded text-sm font-mono",
		pre: "bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto",
		blockquote: "border-l-4 border-blue-500 pl-4 italic text-gray-600",
		hr: "my-8 border-gray-300",
		table: "w-full border-collapse mb-4",
		th: "bg-gray-100 p-3 text-left font-semibold border",
		td: "p-3 border",
	}}
/>

Inline Styles (customStyles)

Apply inline styles using the customStyles prop for complete control:

<TermsOfService
	customStyles={{
		container: {
			maxWidth: "800px",
			margin: "0 auto",
			padding: "2rem",
			backgroundColor: "#ffffff",
			borderRadius: "8px",
			boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
		},
		h1: {
			fontSize: "2.5rem",
			fontWeight: "bold",
			color: "#1a1a1a",
			marginTop: "2rem",
			marginBottom: "1rem",
			fontFamily: "Georgia, serif",
		},
		p: {
			fontSize: "1rem",
			lineHeight: "1.75",
			color: "#4a4a4a",
			marginBottom: "1rem",
		},
		ul: {
			marginBottom: "1rem",
			paddingLeft: "1.5rem",
			listStyleType: "disc",
		},
		li: {
			marginBottom: "0.5rem",
			lineHeight: "1.6",
		},
		a: {
			color: "#2563eb",
			textDecoration: "underline",
		},
	}}
/>

Combining Methods

You can combine className, markdownClassNames, and customStyles for maximum flexibility:

<TermsOfService
	className="my-custom-container"
	markdownClassNames={{
		h1: "text-3xl font-bold",
		p: "text-gray-700",
	}}
	customStyles={{
		h1: {
			color: "#1a1a1a", // Overrides any conflicting CSS class
		},
		p: {
			lineHeight: "1.8", // Adds to CSS class styles
		},
	}}
/>

Styleable Elements

The following markdown elements can be styled:

ElementmarkdownClassNames KeycustomStyles Key
Containercontainercontainer
Headings (h1-h6)h1, h2, h3...h1, h2, h3...
Paragraphpp
Lists (ul, ol, li)ul, ol, liul, ol, li
Linksaa
Code (inline & block)code, precode, pre
Tablestable, th, td...table, th, td...

Common Examples

Dark Mode

<TermsOfService
	theme="dark"
	customStyles={{
		container: {
			backgroundColor: "#1f2937",
			color: "#f9fafb",
		},
		h1: { color: "#ffffff" },
		p: { color: "#d1d5db" },
		a: { color: "#60a5fa" },
	}}
/>

Minimalist Design

<TermsOfService
	customStyles={{
		container: {
			maxWidth: "600px",
			margin: "0 auto",
			padding: "3rem 1rem",
		},
		h1: {
			fontSize: "1.75rem",
			fontWeight: "300",
			marginBottom: "2rem",
			letterSpacing: "-0.02em",
		},
		p: {
			fontSize: "0.9375rem",
			lineHeight: "1.7",
			marginBottom: "1.25rem",
		},
	}}
/>

Hooks

useDocumentContent()

Fetch document markdown content for a given document type.

import { useDocumentContent } from "appclerk-react";

function PrivacySection() {
  const { data, loading, error } = useDocumentContent({
    documentType: "privacy-policy",
  });

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return <pre>{data?.content}</pre>;
}

useComplianceStatus()

Fetch overall compliance status for your project and keep it updated.

import { useComplianceStatus } from "appclerk-react";

function ComplianceBadge() {
  const { data, loading } = useComplianceStatus({
    refreshInterval: 60000, // refresh every minute
  });

  if (loading) return <div>Checking compliance…</div>;

  return <div>Compliance score: {data?.score}%</div>;
}

Examples

Next.js Route Handler

// app/api/compliance/route.ts
import { init } from "appclerk-core";
import { NextResponse } from "next/server";

const appclerk = init({
  apiKey: process.env.APPCLERK_API_KEY!,
  projectId: process.env.APPCLERK_PROJECT_ID!,
});

export async function GET() {
  const compliance = await appclerk.getComplianceStatus();
  return NextResponse.json(compliance);
}

Vite React Component

import { PrivacyPolicy } from "appclerk-react";

export function LegalPage() {
  return (
    <main>
      <h1>Privacy Policy</h1>
      <PrivacyPolicy renderMode="native" displayMode="inline" />
    </main>
  );
}

Getting Started

To use the SDK, you need an API key and project ID from your AppClerk dashboard.

  1. Sign up for AppClerk or log in to your account
  2. Create a project in your dashboard
  3. Generate an API key from API Keys settings
  4. Install the package and start using it in your React app.