{issued}

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/react

Minimal 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 fields object (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.