React
A React component wrapper around the JavaScript SDK. Handles mount/unmount for you and exposes a ref for imperative control.
Install
bash
npm install @issued/reactMinimal embed
tsx
import { IssuedForm } from '@issued/react';
export function SupportForm() {
return (
<IssuedForm
projectId="your-project-id"
fields={{
subject: { visible: true, required: true },
description: { visible: true, required: true },
email: { visible: true, required: false }
}}
callbacks={{
onSuccess: (response) => {
console.log('Submitted:', response.ticketId);
}
}}
/>
);
}Pre-fill from context
A common pattern: pull the signed-in user's email and ID from your auth context and send them as hidden fields so every issue has that context attached automatically.
tsx
import { IssuedForm } from '@issued/react';
import { useUser } from '@/hooks/useUser';
export function SupportForm() {
const user = useUser();
return (
<IssuedForm
projectId="your-project-id"
fields={{
subject: { visible: true, required: true },
description: { visible: true, required: true },
email: { visible: false, value: user.email },
userId: { visible: false, value: user.id },
plan: { visible: false, value: user.plan }
}}
/>
);
}Imperative control via ref
Trigger validate / submit / reset from outside the component.
tsx
import { useRef } from 'react';
import { IssuedForm, type IssuedFormRef } from '@issued/react';
export function SupportForm() {
const formRef = useRef<IssuedFormRef>(null);
const handleExternalSubmit = async () => {
const result = await formRef.current?.submit();
console.log(result);
};
return (
<>
<IssuedForm ref={formRef} projectId="..." fields={{ /* ... */ }} />
<button onClick={handleExternalSubmit}>Submit elsewhere</button>
</>
);
}Styling & callbacks
The React component accepts the same theme and callbacks props as the core SDK — see the styling guide and callbacks reference.
Gotchas
- Works with React 17+. The component is client-only — mark pages with
'use client'in Next.js App Router. - Don't remount on every render. Memoize the
fieldsobject (or declare it outside the component) to avoid re-initializing the widget on each parent render. - If you need the JS config-object form (for code-sharing with a non-React app), pass
config={...}instead of the flat props.
Next steps
See the fields reference and grab your embed code.