Platforms · React Native

React Native

Submit support requests from a native React Native form through the Issued REST API.

01

Package availability

@issued/react-nativeis not currently published to npm. Use the REST integration below for now; it only relies on React Native's built-in fetch.

02

Submission hook

Add this hook to your app, then build the form UI with normal React Native inputs.

useIssuedSubmission.ts
import { useCallback, useState } from 'react';

const ISSUED_ENDPOINT = 'https://issued.dev/api/submissions';

type SubmissionResponse = {
  success: boolean;
  ticketId?: string;
  message?: string;
  error?: string;
};

export function useIssuedSubmission(projectId: string, bundleId: string) {
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [error, setError] = useState<Error | null>(null);

  const submit = useCallback(async (fields: Record<string, unknown>) => {
    setIsSubmitting(true);
    setError(null);

    try {
      const response = await fetch(ISSUED_ENDPOINT, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-SDK-Platform': 'react-native',
          'X-SDK-Version': 'rest-1.0.0',
          'X-Bundle-ID': bundleId,
        },
        body: JSON.stringify({
          projectId,
          fields,
          metadata: {
            sdk_platform: 'react-native',
            sdk_version: 'rest-1.0.0',
          },
        }),
      });

      const result = (await response.json()) as SubmissionResponse;
      if (!response.ok || !result.success) {
        throw new Error(result.error || result.message || 'Submission failed');
      }

      return result;
    } catch (cause) {
      const nextError =
        cause instanceof Error ? cause : new Error('Submission failed');
      setError(nextError);
      throw nextError;
    } finally {
      setIsSubmitting(false);
    }
  }, [bundleId, projectId]);

  return { submit, isSubmitting, error };
}
03

Submit field values

SupportScreen.tsx
const { submit, isSubmitting, error } = useIssuedSubmission(
  'your-project-id',
  'com.yourcompany.app',
);

const onPress = async () => {
  const result = await submit({
    subject: 'Crash on checkout',
    description: 'The app closes after I tap Pay.',
    email: 'customer@example.com',
    name: 'Ada Customer',
  });

  Alert.alert('Submitted', 'Ticket: ' + result.ticketId);
};

The fields object contains submitted values, not form configuration. Subject and description should be strings.

04

Request body

The hook sends the following JSON shape to https://issued.dev/api/submissions:

POST body
{
  "projectId": "your-project-id",
  "fields": {
    "subject": "Crash on checkout",
    "description": "The app closes after I tap Pay.",
    "email": "customer@example.com",
    "name": "Ada Customer"
  },
  "metadata": {
    "sdk_platform": "react-native",
    "sdk_version": "rest-1.0.0"
  }
}
05

Gotchas

  • Your app's bundle ID must be in the project's allowlist. Update it in the project edit page under Bundle IDs.
  • Use https://issued.dev/api/submissions. The api.issued.dev hostname is not used.
  • Device and app metadata are not collected automatically in the REST integration. Add any non-sensitive context you need under metadata.
Next steps

Copy the React Native snippet with your project ID pre-filled.