TPTruPDF

Advanced setup

Beyond Quick setup: environment variables, self-hosted services, secure mode, AI providers, storage adapters, custom domains, and Docker.

Environment variables

Browser-side (Next.js, Vite, CRA, …)

The viewer reads these at runtime. Prefix names match your bundler's public-env convention (NEXT_PUBLIC_ shown).

VariablePurposeRequired?
NEXT_PUBLIC_TRUPDF_LICENSESigned license tokenyes
NEXT_PUBLIC_TRUPDF_LICENSE_BASE_URLLicense-server origin (heartbeat, revocation feed)yes
NEXT_PUBLIC_TRUPDF_SAMPLE_URLSample PDF URL for the demo routedemo only
NEXT_PUBLIC_CONVERTER_URLBase URL of your @trupdf/converter deploymentconversion
NEXT_PUBLIC_TRUPDF_CONVERTER_API_KEYConverter API key (passed via converterApiKey)conversion
NEXT_PUBLIC_TRUPDF_DOCSERVICE_URLBase URL of the TruPDF document serviceredaction
NEXT_PUBLIC_TRUPDF_AI_ANTHROPIC_KEYAnthropic API keyAI
NEXT_PUBLIC_TRUPDF_AI_GEMINI_KEYGoogle Gemini keyAI
NEXT_PUBLIC_TRUPDF_AI_OPENROUTER_KEYOpenRouter keyAI
NEXT_PUBLIC_TRUPDF_AI_OPENROUTER_BASE_URLOpenRouter base URL overrideAI
NEXT_PUBLIC_TRUPDF_AI_OPENAI_COMPATIBLE_BASE_URLCustom OpenAI-compatible LLM endpointAI
NEXT_PUBLIC_TRUPDF_AI_OPENAI_COMPATIBLE_KEYCustom LLM keyAI
NEXT_PUBLIC_TRUPDF_AI_MODELModel override (e.g., claude-3-5-sonnet)AI

URLs must come from env vars and fail loudly when missing. No hard-coded localhost. CORS origins must be explicit too — never wildcarded in production.

Server-side (conversion + document services)

These are read by the @trupdf/converter and document-service processes, not the browser bundle.

Internal service wiring (engine, queue, cache) is preconfigured by the bundled docker-compose.yml; you only set the variables below.

@trupdf/converter

VariablePurpose
TRUPDF_LICENSESigned license (verified on startup)
TRUPDF_LICENSE_DEV_MODE1 = synthetic enterprise (dev only; logged at WARN)
TRUPDF_CONVERTER_API_KEYAPI key clients must send (required in production)
STORAGE_ADAPTERlocal / s3 / azure / webhook
LOCAL_STORAGE_DIRDefault /data/storage
LOCAL_STORAGE_PUBLIC_URLPublic URL prefix for local storage
S3_BUCKET / S3_REGION / S3_ENDPOINT / S3_KEY_PREFIXS3 / MinIO config
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEYAWS credentials
S3_URL_EXPIRYPresigned URL TTL (seconds)
S3_FORCE_PATH_STYLE1 for MinIO
AZURE_ACCOUNT_NAME / AZURE_ACCOUNT_KEY / AZURE_CONTAINER / AZURE_URL_EXPIRY / AZURE_KEY_PREFIXAzure Blob config
WEBHOOK_STORE_URL / WEBHOOK_RETRIEVE_URL / WEBHOOK_EXISTS_URL / WEBHOOK_DELETE_URL / WEBHOOK_TOKEN / WEBHOOK_HMAC_SECRETWebhook adapter (custom HTTP sink)
CORS_ORIGINSComma list of allowed origins (required)
CONVERSION_TIMEOUT_MSPer-job timeout. Default 1800000 (30 min)
MAX_UPLOAD_BYTESUpload size cap. Default 0 (unlimited)
CACHE_TTL_SECONDSResult-cache TTL. Default 604800 (7 days)
RETENTION_SWEEP_INTERVAL_MSHow often stored results are swept
RETENTION_MAX_AGE_MSMax age of stored results before deletion
LOG_LEVELdebug / info / warn / error
PORTDefault 3002

The TruPDF document service (structural redaction + PDF/A validation)

VariablePurpose
TRUPDF_CORS_ORIGINSComma list of allowed origins
JAVA_OPTSService memory flags (-Xmx512m recommended for 50-page docs)

DocViewer props

The main component accepts every prop the viewer exposes. See Features → Viewer for the full table; the ones you'll set most often:

<DocViewer
  source="/files/sample.pdf"
  licenseManager={license}
  theme="system" // 'light' | 'dark' | 'system'
  initialScale={1.25}
  secureMode={false}
  showThumbnails
  showComments
  modularConfig="default-ui" // or a custom JSON config
  mode="view" // 'view' | 'compare'
  language="en" // any of the 31 locales
  converterUrl={process.env.NEXT_PUBLIC_CONVERTER_URL}
  converterApiKey={process.env.NEXT_PUBLIC_TRUPDF_CONVERTER_API_KEY}
  aiConfig={aiConfig}
  onPasswordRequired={async () => promptUserForPassword()}
  onDocumentLoaded={(doc) => analytics.track('opened', { pages: doc.numPages })}
  onError={(err) => Sentry.captureException(err)}
  engineRef={(engine) => {
    window.__trupdf = engine;
  }}
/>

Self-host the conversion service

Non-PDF inputs (Office documents, HTML, images, text, markdown, email, XPS, XOD, 2D CAD) round-trip via the TruPDF conversion engine behind @trupdf/converter. One command brings up all three containers:

docker-compose up -d

docker-compose.yml ships:

  • the conversion engine (port 3001) — office + HTML render pipelines.
  • the result cache (port 6379) — backs the job queue and dedupes repeat conversions.
  • the converter orchestrator (port 3002) — the @trupdf/converter HTTP API your app talks to.

Then point your browser bundle:

# .env.local
NEXT_PUBLIC_CONVERTER_URL=http://localhost:3002

The viewer detects non-PDF input and POSTs to /convert (or POST /convert/async + GET /convert/jobs/:id for long-running jobs), then loads the resulting PDF stream. Trial licences do not include the convert feature — paid tiers do by default.

See Features → Conversion for the route table and supported formats.

Self-host the TruPDF document service

Redaction is a sensitive op. The engine refuses to burn unless a structural adapter is registered — there is no visual-only fallback. The reference adapter is the document-service redaction adapter, backed by the self-hosted TruPDF document service container.

docker compose --profile phase8 up -d

At app boot, bind the document-service redaction adapter:

import { bindPdfboxRedactionAdapter } from '@trupdf/security';
 
bindPdfboxRedactionAdapter({
  endpoint: process.env.NEXT_PUBLIC_TRUPDF_DOCSERVICE_URL!,
});

See Features → Security for the full redaction flow.

The same service exposes POST /validate/pdfa — full ISO 19005 (PDF/A) validation, consumed by sdk.validatePdfA(). See Features → PDF/A & Tagged PDF.

Secure mode

secureMode: true removes the DOM text layer, blocks Ctrl+C / Cut / Drag / right-click, adds canvas-level overlays, and lets DRM permission checks short-circuit selection. AI features that read text content auto-disable in secure mode.

<DocViewer source="…" licenseManager={license} secureMode />

When secure mode is on:

  • Text layer DOM is never mounted.
  • Selection menus, search highlight overlays, and copy-text shortcuts short-circuit.
  • The AI "Explain Selection" tool falls back to a page-image-only pipeline if the host enables the OCR fallback.
  • Screen readers receive a live region with structural reading order via @trupdf/a11y.

AI provider configuration

Pass aiConfig to DocViewer. Pick one provider — Anthropic, Gemini, OpenRouter, or any OpenAI-compatible endpoint (Ollama, vLLM, LM Studio, on-prem MCP server, …).

import type { AIConfig } from '@trupdf/viewer';
 
const aiConfig: AIConfig = {
  provider: 'anthropic',
  apiKey: process.env.NEXT_PUBLIC_TRUPDF_AI_ANTHROPIC_KEY!,
  model: 'claude-3-5-sonnet-latest',
  // Optional:
  secureMode: false,
  cachePages: true,
  abortOnUnmount: true,
};
 
<DocViewer source="…" licenseManager={license} aiConfig={aiConfig} />;

See Features → AI for the full configuration matrix and provider notes.

Plugins

Register custom tools, toolbar buttons, sidebar panels, and menu items via the SDK. Plugins are typed objects with optional lifecycle hooks; one install() per plugin.

import { TruPDFSDK, type TruPDFPlugin } from '@trupdf/viewer';
 
const sdk = new TruPDFSDK({ licenseManager: license });
 
const reviewPlugin: TruPDFPlugin = {
  id: 'mark-reviewed',
  toolbar: [
    {
      id: 'mark-reviewed',
      label: 'Mark reviewed',
      icon: '✓',
      hotkey: 'Mod+R',
      handler: (api) => api.events.emit('plugin.toolbar.action', { id: 'mark-reviewed' }),
    },
  ],
  onInit: async (api) => {
    /* … */
  },
};
 
await sdk.install(reviewPlugin);

See Customization → Plugins for the full surface.

Theming

Override CSS custom properties on .trupdf-viewer (or any ancestor):

.trupdf-viewer[data-theme='light'] {
  --trupdf-accent: #2563eb;
  --trupdf-bg: #ffffff;
  --trupdf-fg: #0f172a;
}

See Customization → Theming for the full token reference.

Production hardening checklist

  • License token loaded from env, never source-controlled.
  • LicenseManager.destroy() called on host unmount.
  • urlBase (license server) configured for staging/production separately.
  • Heartbeat reachable on outbound 443 from production network.
  • Storage adapter set to S3 / Azure / Webhook (not local).
  • CORS_ORIGINS explicitly set on the conversion + document services.
  • TRUPDF_CONVERTER_API_KEY set on the converter and mirrored to the viewer via converterApiKey.
  • The render worker ships inside the package — no extra worker hosting or CSP entry needed.
  • secureMode enabled where the document policy demands it.
  • Sentry / log sink wired to onError, LicenseExpired, LicenseRevoked, HeartbeatStale.
  • Audit log subscribers forwarding to your backend.
  • License Server's revocation feed reachable (cached RevocationCache falls back to localStorage; clearing storage forces a refresh).

See also

  • Licensing — full token format, heartbeat, revocation, domain matching.
  • Architecture — three-layer rendering pipeline, coordinate systems.
  • Compatibility — XFDF, forms, signed PDFs, browser matrix.