Skip to content

Intégrer QForm Builder dans une application Nuxt 4 existante

Cette page s’adresse aux applications Nuxt 4 déjà en place : dashboard, portail admin, NFZ Studio, back-office ou extranet.

1. Ajouter le layer

Deux modes sont possibles.

Mode local

txt
my-app/
├── app/
├── layers/
│   └── qform-builder/
└── nuxt.config.ts
ts
// nuxt.config.ts
export default defineNuxtConfig({
  extends: ['./layers/qform-builder']
})

Mode package npm

bash
bun add @vevedh/qform-builder-layer \
  nuxt-quasar-ui @pinia/nuxt @formkit/nuxt \
  quasar @quasar/extras \
  @formkit/core @formkit/i18n @formkit/vue @formkit/utils
ts
// nuxt.config.ts
export default defineNuxtConfig({
  extends: ['@vevedh/qform-builder-layer']
})

2. Vérifier les modules déjà présents

Le layer configure déjà :

txt
nuxt-quasar-ui
@pinia/nuxt
@formkit/nuxt

Si ton application utilise déjà Quasar, Pinia ou FormKit, vérifie que les versions sont compatibles et évite les doubles configurations contradictoires.

3. Attention au SSR

Le layer ne force plus ssr: false. Ce choix appartient à l’application hôte.

FormBuilder reste un composant fortement interactif : Quasar, drag and drop, window, document, localStorage, interactions souris/clavier. Dans une application SSR, utilise-le dans ClientOnly :

vue
<ClientOnly>
  <FormBuilder builder-id="admin-builder" />
</ClientOnly>

FormViewer est plus proche du runtime, mais il faut tout de même valider les composants Quasar/FormKit utilisés selon ta stratégie SSR.

4. Page d’intégration recommandée

vue
<!-- app/pages/admin/forms/[id].vue -->
<script setup lang="ts">
import type { FormKitSchemaDefinition } from '@formkit/core'

type FormBuilderSchema = FormKitSchemaDefinition[]
type FormBuilderValues = Record<string, unknown>

type FormDocument = {
  id: string
  name: string
  schema: FormBuilderSchema
  values: FormBuilderValues
  updatedAt?: string
}

const route = useRoute()
const formId = computed(() => String(route.params.id || 'new'))
const builderId = computed(() => `admin-form-${formId.value}`)

const document = ref<FormDocument>({
  id: formId.value,
  name: 'Nouveau formulaire',
  schema: [],
  values: {}
})

function handleSave(payload: {
  builderId: string
  schema: FormBuilderSchema
  values: FormBuilderValues
  settings: Record<string, unknown>
}) {
  document.value = {
    ...document.value,
    schema: payload.schema,
    values: payload.values,
    updatedAt: new Date().toISOString()
  }

  // Remplacer ensuite par formsStore.save(document.value)
  console.log('Document prêt à sauvegarder', document.value)
}
</script>

<template>
  <ClientOnly>
    <FormBuilder
      :builder-id="builderId"
      v-model:schema="document.schema"
      v-model:values="document.values"
      :title="document.name"
      subtitle="Édition du formulaire métier"
      autosave
      @save="handleSave"
    />
  </ClientOnly>
</template>

5. Pattern conseillé pour une app existante

Évite de connecter directement le composant à l’API. Utilise cette séparation :

txt
Page Nuxt

Store métier Pinia

Repository / composable API

Service Feathers/NFZ ou endpoint existant

Exemple de découpage :

txt
app/pages/admin/forms/[id].vue
app/stores/formsAdminStore.ts
app/composables/useFormsRepository.ts

Ce pattern permet de garder FormBuilder portable et de remplacer le backend sans toucher au composant.

QForm Builder — couche Nuxt 4 / Quasar / FormKit réutilisable.