Platforms · JavaScript

JavaScript

Drop the Issued script into any HTML page. The widget renders into a container you provide and posts submissions to your project.

01

Install

No package to install — reference the hosted script directly.

<script src="https://issued.dev/widget/issued.js"></script>
02

Minimal embed

Render a container, then call Issued.init(...) with your project ID. Copy your real project ID from the Embed Code page in the dashboard.

index.html
<div id="issued-widget-container"></div>

<script src="https://issued.dev/widget/issued.js"></script>
<script>
  Issued.init({
    projectId: "your-project-id",
    fields: {
      subject:     { visible: true, required: true, label: "Subject" },
      description: { visible: true, required: true, label: "Description" },
      email:       { visible: true, required: false, label: "Email" }
    }
  });
</script>
03

Hidden metadata

Pass fields with visible: false and a value to attach context (user ID, plan tier, app version, page URL) to every issue automatically.

Issued.init({
  projectId: "your-project-id",
  fields: {
    subject:     { visible: true, required: true },
    description: { visible: true, required: true },
    email:       { visible: false, value: currentUser.email },
    userId:      { visible: false, value: currentUser.id },
    pageUrl:     { visible: false, value: window.location.href },
    appVersion:  { visible: false, value: "2.4.1" }
  }
});

The full list of built-in fields (and the provider-specific ones like github_labels and linear_labels) lives in the fields reference.

04

Styling

Pass a theme object to match your brand. Full property list in the styling guide.

Issued.init({
  projectId: "your-project-id",
  fields: { /* ... */ },
  theme: {
    mode: "auto",             // "auto" | "light" | "dark"
    primaryColor: "#6366f1",
    errorColor: "#dc2626",
    successColor: "#059669",
    borderRadius: "8px",
    fontFamily: "Inter, sans-serif"
  }
});
05

Callbacks

Hook into the submission lifecycle — gate submissions, toast on success, or capture validation errors for analytics.

Issued.init({
  projectId: "your-project-id",
  fields: { /* ... */ },
  callbacks: {
    onBeforeSubmit: (formData) => {
      // Return false to cancel the submission.
      return agreeToTerms();
    },
    onSuccess: ({ ticketId }) => {
      console.log("Submitted:", ticketId);
    },
    onError: (err) => {
      console.error(err);
    },
    onValidationError: (errors) => {
      // { subject: ["Subject is required"], ... }
    }
  }
});

See every callback signature in the callbacks reference.

06

Gotchas

  • The container element must exist in the DOM before Issued.init(...) runs. If you call it from a dynamically mounted component, ensure the container is rendered first.
  • Your page's origin must be in the project's whitelisted domains or submissions will be rejected with a 403 INVALID_ORIGIN. Toggle localhost access on in project settings while developing.
  • The default container ID is issued-widget-container. Pass container: "#my-id" to target a different element.
Next steps

Grab your real project embed code from the dashboard.