Skip to content
Working With React

Next.js client forms

Connect Next.js App Router client forms to Qubeforms without a custom API route. Configure public endpoints, allowed origins, and production or preview deployments.

1. Use the App Router client boundary

The React form uses state and event handlers, so place 'use client'; at the very top of app/components/ContactForm.jsx, before its imports. Copy the complete component from A React form component below that directive. The page importing it may remain a Server Component. The form posts from the visitor’s browser directly to Qubeforms; this workflow does not require a Server Action or Route Handler.

'use client';

// Follow this directive with the ContactForm component from the React guide.

2. Set the public endpoint

In your Next.js project, define NEXT_PUBLIC_QUBEFORMS_ENDPOINT in .env.local for development and in the deployment’s build environment for production. A NEXT_PUBLIC_ value is included in the browser bundle at build time; changing only a running server’s environment does not change the previously built value. Rebuild when promoting a bundle that needs a different endpoint. Keep private credentials out of all public environment variables.

NEXT_PUBLIC_QUBEFORMS_ENDPOINT=https://api.qubeforms.io/v1/cf_pk_YOUR_KEY/submissions

3. Render the contact page

This app/contact/page.jsx example imports the client form and passes a string endpoint. Adjust the import if your directories differ. For TypeScript projects use the corresponding .tsx files and type the component props and events. The examples here use JavaScript.

import ContactForm from '../components/ContactForm';

export default function ContactPage() {
  const endpoint = process.env.NEXT_PUBLIC_QUBEFORMS_ENDPOINT;
  if (!endpoint) return <p>The contact form is not configured yet.</p>;
  return <ContactForm endpoint={endpoint} />;
}

4. Configure production and preview origins

Add your Next.js website origin under Qubeforms Allowed origins. Add http://localhost:3000 only when that is your actual local origin. Preview deployment hosts also need matching rules; use explicit preview origins or a wildcard only for a domain you intend to trust. A separate test form keeps preview traffic out of your production inbox. Do not add the Qubeforms API origin as a substitute for the website origin.

5. Keep browser and server work separate

Initialize browser-only state after mounting or during a user event. Do not submit from a Server Component render, and do not expose read keys to a client component. If you later use a Route Handler to read private submissions, authenticate the caller in that backend and keep the read key there. Server Actions and Route Handlers may have their own request-size constraints; the direct browser upload example does not pass attachments through them.

6. Check deployment problems

If the endpoint is missing, check its exact name, restart local development, or rebuild with the production value. Hydration mismatches can come from rendering timestamps or browser storage on the server. CORS errors usually involve the saved website origin or request URL. If JSON returns redirect_url, navigation is your client code’s responsibility. Test the deployed site itself, not just localhost.

Keep private credentials private

Public form keys can appear in browser code. Read keys, management credentials, and webhook signing secrets must stay on the server.