React Integration (Full Guide)
This guide walks through a complete React integration: loading the SDK, rendering the editor, listening for events, and generating PDFs via the API. For the component wrapper reference, see React.
1. Install and Register
Section titled “1. Install and Register”npm install @glyph-sdk/web<script type="module" src="https://sdk.glyph.you/glyph-editor.js"></script>Register once at your app entry point:
import '@glyph-sdk/web';2. Render the Editor
Section titled “2. Render the Editor”The <glyph-editor> web component works directly in JSX. Pass data as a JSON string:
function InvoiceEditor({ invoice }) { const editorRef = useRef<HTMLElement>(null);
return ( <glyph-editor ref={editorRef} api-key={import.meta.env.VITE_GLYPH_API_KEY} base-url="https://api.glyph.you" template="quote-modern" data={JSON.stringify(invoice)} /> );}3. Handle Events
Section titled “3. Handle Events”The editor emits Custom Events. Attach listeners in a useEffect:
useEffect(() => { const el = editorRef.current; if (!el) return;
const onReady = () => console.log('Editor ready'); const onModified = (e: CustomEvent) => { console.log('Modified:', e.detail.prompt); // e.detail.html contains the updated HTML }; const onError = (e: CustomEvent) => { console.error(e.detail.code, e.detail.message); };
el.addEventListener('glyph:ready', onReady); el.addEventListener('glyph:modified', onModified); el.addEventListener('glyph:error', onError);
return () => { el.removeEventListener('glyph:ready', onReady); el.removeEventListener('glyph:modified', onModified); el.removeEventListener('glyph:error', onError); };}, []);Available events: glyph:ready, glyph:modified, glyph:saved, glyph:error, glyph:region-selected. See Events for details.
4. Trigger Modifications Programmatically
Section titled “4. Trigger Modifications Programmatically”Call methods on the element ref:
async function applyChange(prompt: string) { const editor = editorRef.current as any; await editor.modify(prompt);}
// Undo / redoeditor.undo();editor.redo();5. Generate a PDF via the API
Section titled “5. Generate a PDF via the API”You can generate PDFs either through the SDK or by calling the API directly from your server.
Client-side (via SDK)
Section titled “Client-side (via SDK)”async function downloadPdf() { const editor = editorRef.current as any; const blob = await editor.generatePdf(); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'document.pdf'; a.click(); URL.revokeObjectURL(url);}Server-side (Node.js / Next.js API route)
Section titled “Server-side (Node.js / Next.js API route)”Keep your API key on the server. Fetch the session HTML from the client, then call the generate endpoint:
// pages/api/generate-pdf.ts (Next.js example)export default async function handler(req, res) { const { html } = req.body;
const response = await fetch('https://api.glyph.you/v1/generate', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.GLYPH_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ html, format: 'pdf' }), });
if (!response.ok) { const error = await response.json(); return res.status(response.status).json(error); }
const buffer = Buffer.from(await response.arrayBuffer()); res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'attachment; filename="document.pdf"'); res.send(buffer);}6. Full Working Example
Section titled “6. Full Working Example”A minimal but complete React app:
import { useRef, useEffect, useState } from 'react';import '@glyph-sdk/web';
const sampleData = { client: { name: 'Acme Corp', email: 'billing@acme.com' }, lineItems: [ { description: 'API Integration', quantity: 1, unitPrice: 5000, total: 5000 }, { description: 'Support (monthly)', quantity: 3, unitPrice: 500, total: 1500 }, ], totals: { subtotal: 6500, tax: 520, total: 7020 }, meta: { quoteNumber: 'Q-2025-001', date: 'Jan 15, 2025' },};
export default function App() { const ref = useRef<HTMLElement>(null); const [ready, setReady] = useState(false);
useEffect(() => { const el = ref.current; if (!el) return; const handler = () => setReady(true); el.addEventListener('glyph:ready', handler); return () => el.removeEventListener('glyph:ready', handler); }, []);
return ( <div style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}> <header style={{ padding: '1rem', borderBottom: '1px solid #e5e5e5' }}> <button disabled={!ready} onClick={async () => { const blob = await (ref.current as any).generatePdf(); const url = URL.createObjectURL(blob); window.open(url); }} > Download PDF </button> </header> <glyph-editor ref={ref} api-key={import.meta.env.VITE_GLYPH_API_KEY} base-url="https://api.glyph.you" template="quote-modern" data={JSON.stringify(sampleData)} style={{ flex: 1 }} /> </div> );}Next Steps
Section titled “Next Steps”- React Component Wrapper — typed wrapper with
forwardRefand Zustand examples - Custom Templates — build your own template
- Batch Generation — generate multiple PDFs in one API call