Skip to content
Working With Vue

Nuxt client forms

Connect Nuxt client forms to Qubeforms with public runtime configuration. Set endpoint environment variables, submit from browser event handlers, and test deployment.

1. Keep interactive submission in the browser

Use the Vue 3 component from A Vue form component. Its submit handler runs after user interaction, so it can use FormData and browser fetch without posting during server rendering. You do not need to wrap the whole form in ClientOnly or add a Nuxt server endpoint for this direct submission workflow. Keep DOM access in event handlers or onMounted.

2. Declare public runtime configuration

Add this key in nuxt.config.ts. Only the public submission endpoint belongs in runtimeConfig.public; Nuxt exposes it to the browser. The declaration lets an environment variable with the matching Nuxt name override it. Private read keys, AWS credentials, and management secrets must not be placed here.

export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      qubeformsEndpoint: '',
    },
  },
});

3. Set the matching environment variable

Use NUXT_PUBLIC_QUBEFORMS_ENDPOINT in the Nuxt project’s development .env and in your production deployment environment. It maps to runtimeConfig.public.qubeformsEndpoint. A running production Nuxt server does not automatically load your development .env; configure the host environment. For a generated static site, supply the value during generation and regenerate when it changes. These values configure the customer’s Nuxt application, not Qubeforms itself.

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

4. Render the contact page

For a Nuxt 4 project, save the component as app/components/ContactForm.vue and use this page in app/pages/contact.vue. In projects with a Nuxt 3-style directory layout, use components/ and pages/ instead. The component is auto-imported from the components directory. useRuntimeConfig() supplies the endpoint to both server rendering and client hydration.

<script setup>
const config = useRuntimeConfig();
</script>

<template>
  <ContactForm
    v-if="config.public.qubeformsEndpoint"
    :endpoint="config.public.qubeformsEndpoint"
  />
  <p v-else>The contact form is not configured yet.</p>
</template>

5. Use an event handler for mutations

Do not use useFetch or useAsyncData in page setup to submit visitor data; those utilities are intended for data loading and can run during rendering. The example uses native fetch in the submit event. If you replace it with $fetch, account for its error behavior rather than treating it as a browser Response. Allow the actual development, preview, and production website origins in Qubeforms, and keep private read-API calls in an authenticated backend.

6. Test the built site

If the form is unconfigured, check the declared config key and the matching environment name. If a generated site still uses an old endpoint, regenerate it. Check the Network panel for the browser’s origin and the API response. Test a successful submission, an error that preserves fields, uploads on a paid plan, and CAPTCHA if enabled. Do not use no-cors to hide a failing request.

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.