{issued}

JavaScript

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

Install

No package to install — reference the hosted script directly.

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

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.

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>

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.

js
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.

Styling

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

js
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"
  }
});

Callbacks

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

js
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.

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.