diff --git a/craft-freeform/headless/getting-started.mdx b/craft-freeform/headless/getting-started.mdx
new file mode 100644
index 00000000..a7ce8013
--- /dev/null
+++ b/craft-freeform/headless/getting-started.mdx
@@ -0,0 +1,166 @@
+---
+title: Getting Started
+sidebar_position: 1
+description: Install and enable Freeform's official headless React packages for Craft CMS.
+---
+
+import { Badge, BadgeGroup } from '@site/src/components/utils';
+import { VerticalStepWrapper, StepMarkdown } from '@site/src/components/docs';
+
+# Getting Started (React Headless)
+
+Freeform’s recommended headless path for React and Next.js is:
+
+1. Use a Freeform plugin build that includes the **headless REST API**
+2. Enable headless in Freeform config
+3. Install the official npm packages (`0.1.0`)
+4. Render forms with `` or build your own UI with `useFreeform()`
+
+GraphQL and older AJAX demos remain available, but new React/Next.js projects should start here.
+
+:::tip Example app
+Clone the [Freeform Headless React Demo](https://github.com/solspace/freeform-headless-react-demo) to try the packages against your Craft site.
+:::
+
+## Requirements
+
+| Piece | Version / notes |
+| --- | --- |
+| Craft CMS | 4.17+ or 5.9+ |
+| Freeform plugin | Build that includes headless REST |
+| npm packages | **`0.1.0`** ([npm org](https://www.npmjs.com/org/solspace)) |
+| React | 18 or 19 |
+| Node | Modern LTS with `npm` / `pnpm` / `yarn` |
+
+## Quick setup
+
+
+
+
+Headless is **off by default**. Configure it in your **Craft CMS project** (the site where Freeform is installed) — not in your React / Next.js app repo.
+
+Edit or create:
+
+```text
+your-craft-project/config/freeform.php
+```
+
+That file lives next to Craft’s other config files (`general.php`, `routes.php`, etc.), for example:
+
+```text
+~/Sites/my-craft-site/config/freeform.php
+```
+
+Merge a `headless` section into that file (keep any existing Freeform settings):
+
+```php title="config/freeform.php" showLineNumbers
+ [
+ // Master switch — endpoints return 404 when false
+ 'enabled' => true,
+
+ // CORS origins for browser apps that call Craft directly
+ 'allowedOrigins' => [
+ 'http://localhost:3000',
+ 'https://app.example.com',
+ ],
+
+ // Per-form exposure (keyed by form handle from the Freeform CP)
+ 'forms' => [
+ 'contact' => [
+ 'exposeManifest' => true,
+ 'allowSubmit' => true,
+ ],
+ ],
+ ],
+];
+```
+
+:::tip Same-origin proxy
+If your frontend proxies `/freeform/*` to Craft (recommended for Next.js), CSRF cookies stay same-origin and you can keep `allowedOrigins` tight.
+:::
+
+See the full [REST API](./rest-api.mdx) reference for profiles, CSRF, and submit details.
+
+
+
+
+```bash
+npm install @solspace/freeform-core \
+ @solspace/freeform-react \
+ @solspace/freeform-extensions \
+ @solspace/freeform-react-theme-default
+```
+
+| Package | Purpose |
+| --- | --- |
+| `@solspace/freeform-core` | Manifest client, form state, conditionals, submit |
+| `@solspace/freeform-react` | `` component and `useFreeform()` hook |
+| `@solspace/freeform-extensions` | Captchas, datetime picker, file drag & drop |
+| `@solspace/freeform-react-theme-default` | Default light/dark theme CSS |
+
+
+
+
+```tsx title="ContactForm.tsx" showLineNumbers
+import { Freeform } from '@solspace/freeform-react';
+import { recommendedExtensions } from '@solspace/freeform-extensions';
+import '@solspace/freeform-react-theme-default/styles.css';
+
+export function ContactForm() {
+ return (
+ {
+ console.log('Submitted', response);
+ }}
+ />
+ );
+}
+```
+
+- **`handle`** — Freeform form handle (must be enabled under `headless.forms`)
+- **`baseUrl`** — Craft site origin, **or** `""` / same origin when you proxy `/freeform`
+- **`extensions`** — register captchas and advanced fields when the form needs them
+
+
+
+
+## Choose your guide
+
+| Guide | When to use it |
+| --- | --- |
+| [React JS](./reactjs.mdx) | Vite, CRA, Remix, or any React SPA |
+| [Next.js](./nextjs.mdx) | App Router / Pages Router + proxy |
+| [REST API](./rest-api.mdx) | Endpoints, CSRF, CORS, profiles |
+| [GraphQL](./graphql.mdx) | Existing GraphQL integrations (alternate path) |
+| [Example demo](https://github.com/solspace/freeform-headless-react-demo) | Cloneable Vite app using the published packages |
+
+## What’s included
+
+- Manifest load + CSRF + submit (JSON and multipart)
+- Multi-page forms and conditionals (client UX)
+- Captchas via `@solspace/freeform-extensions`
+- File upload and File Drag & Drop
+- Default theme with light / dark / system color schemes
+
+## Coming later
+
+- Drafts / save & continue
+- Payment fields (Stripe, etc.)
+- Calculation fields
+- Official Vue adapter
+- Bootstrap and Tailwind theme packages
+- Full GraphQL parity with the REST contract
+
+## Security checklist
+
+1. Keep headless **disabled** until you intentionally enable forms.
+2. Set explicit `headless.allowedOrigins` for cross-origin apps.
+3. Enable a **captcha** on public forms (do not rely on honeypot alone for API callers).
+4. Leave **`allowRawHtml` off** unless HTML / rich-text field content is trusted CMS content.
+5. Do not treat client-side conditional hiding as a server access-control boundary yet.
diff --git a/craft-freeform/headless/graphql.mdx b/craft-freeform/headless/graphql.mdx
index ffd6295f..0e0198d6 100644
--- a/craft-freeform/headless/graphql.mdx
+++ b/craft-freeform/headless/graphql.mdx
@@ -1,6 +1,6 @@
---
title: GraphQL
-sidebar_position: 1
+sidebar_position: 6
description: Integrate Freeform 5.x with GraphQL in Craft CMS for headless form handling and submissions.
---
@@ -14,6 +14,10 @@ import { VerticalStepWrapper, StepMarkdown } from '@site/src/components/docs';
Freeform supports querying form layouts and form submission mutations via GraphQL. This guide assumes you have some GraphQL experience. To learn more about GraphQL and Craft, please check out the [Fetch content with GraphQL](https://craftcms.com/docs/getting-started-tutorial/build/graphql.html) guide and [Craft's GraphQL API](https://craftcms.com/docs/5.x/development/graphql.html).
+:::tip New React / Next.js projects
+For new React and Next.js apps, prefer the official packages and [REST API](./rest-api.mdx) — start with [Getting Started](./getting-started.mdx). GraphQL remains fully supported for existing headless integrations.
+:::
+
or build your own UI with useFreeform().',
icon: Icons.ReactIcon,
fullCardLink: 'reactjs',
},
{
title: 'Next.js',
- description: 'Full support for implementation Freeform with Next.js.',
+ description:
+ 'App Router Client Components, rewrites proxy, and CSRF-friendly setup.',
icon: Icons.NextjsIcon,
fullCardLink: 'nextjs',
filterIcon: true,
},
+ {
+ title: 'Vue.js',
+ description:
+ 'Headless demos for Vue.js (official Vue package coming later).',
+ icon: Icons.VuejsIcon,
+ fullCardLink: 'vuejs',
+ },
{
title: 'GraphQL',
description:
- 'With Freeform, you can easily query form layouts and submit form mutations using GraphQL.',
+ 'Query form layouts and create submissions with GraphQL mutations.',
icon: Icons.GraphqlIcon,
fullCardLink: 'graphql',
},
diff --git a/craft-freeform/headless/nextjs.mdx b/craft-freeform/headless/nextjs.mdx
index 4fb897b5..1b2c9a52 100644
--- a/craft-freeform/headless/nextjs.mdx
+++ b/craft-freeform/headless/nextjs.mdx
@@ -1,33 +1,166 @@
---
title: Next.js
sidebar_position: 4
-description: Build headless forms with Freeform 5.x and Next.js in Craft CMS.
+description: Build headless Freeform forms with Next.js and the official React packages for Craft CMS.
---
import { Badge, BadgeGroup } from '@site/src/components/utils';
+import { VerticalStepWrapper, StepMarkdown } from '@site/src/components/docs';
-# Next.js Implementations
+# Next.js
-:::warning
-Please see the [How to Render a Form](./graphql.mdx#how-to-render-a-form) guide for detailed steps for being able to render your own form in the front-end using GraphQL data and Next.js.
-:::
+Use the official `@solspace/freeform-react` packages (`0.1.0`). Complete [Getting Started](./getting-started.mdx) (enable headless + install packages) first.
-## GraphQL Demo
+Freeform’s React packages are client-side. In the App Router, render them from a **Client Component** and proxy `/freeform` so CSRF cookies stay on your Next.js origin.
-The below demo link shows how Freeform is implemented with [Next.js](https://react.dev/) and [GraphQL](./graphql.mdx).
+## Install
-:::info
-Please note that the paths in the demos are specific for the Solspace demo site and server. Please make sure your code uses paths that match your server setup.
-:::
+```bash
+npm install @solspace/freeform-core \
+ @solspace/freeform-react \
+ @solspace/freeform-extensions \
+ @solspace/freeform-react-theme-default
+```
-https://github.com/solspace/craft-freeform-demo-nextjs-graphql
+## Setup
-## AJAX Demo
+
+
-The below demo link shows how Freeform is implemented with [Next.js](https://react.dev/) and AJAX.
+```ts title="next.config.ts" showLineNumbers
+import type { NextConfig } from 'next';
-:::info
-Please note that the paths in the demos are specific for the Solspace demo site and server. Please make sure your code uses paths that match your server setup.
-:::
+const nextConfig: NextConfig = {
+ async rewrites() {
+ return [
+ {
+ source: '/freeform/:path*',
+ destination: `${process.env.CRAFT_URL}/freeform/:path*`,
+ },
+ ];
+ },
+};
-https://github.com/solspace/craft-freeform-demo-nextjs-ajax
+export default nextConfig;
+```
+
+Set `CRAFT_URL` to your Craft site (for example `https://cms.example.com`). Requests from the browser hit `/freeform/...` on the Next.js origin; Next.js forwards them to Craft.
+
+
+
+
+```tsx title="app/contact/contact-form.tsx" showLineNumbers
+'use client';
+
+import { Freeform } from '@solspace/freeform-react';
+import { recommendedExtensions } from '@solspace/freeform-extensions';
+import '@solspace/freeform-react-theme-default/styles.css';
+
+export function ContactForm() {
+ return (
+ {
+ console.log(response);
+ }}
+ />
+ );
+}
+```
+
+```tsx title="app/contact/page.tsx" showLineNumbers
+import { ContactForm } from './contact-form';
+
+export default function ContactPage() {
+ return (
+
+ Contact
+
+
+ );
+}
+```
+
+
+
+
+In `config/freeform.php` on Craft:
+
+```php
+'headless' => [
+ 'enabled' => true,
+ 'forms' => [
+ 'contact' => [
+ 'exposeManifest' => true,
+ 'allowSubmit' => true,
+ ],
+ ],
+],
+```
+
+With the same-origin proxy you usually do **not** need to add the Next.js origin to `allowedOrigins`. Add it only if the browser calls Craft directly.
+
+
+
+
+## Environment variables
+
+| Variable | Where | Example |
+| --- | --- | --- |
+| `CRAFT_URL` | Next.js server (rewrites) | `https://cms.example.com` |
+| `NEXT_PUBLIC_CRAFT_URL` | Optional public Craft URL | Only if you skip the proxy |
+
+Prefer the proxy + `baseUrl=""` pattern over exposing Craft’s origin to the browser.
+
+## Cross-origin (no proxy)
+
+If the browser must call Craft directly:
+
+1. Set `baseUrl={process.env.NEXT_PUBLIC_CRAFT_URL}`
+2. Add your Next.js origin to `headless.allowedOrigins`
+3. Keep credentials enabled (default in the Freeform client)
+
+```tsx
+
+```
+
+## Headless markup
+
+`useFreeform()` works the same as in a Vite React app — still inside a Client Component:
+
+```tsx
+'use client';
+
+import { useFreeform } from '@solspace/freeform-react';
+
+export function HeadlessContactForm() {
+ const form = useFreeform({
+ handle: 'contact',
+ baseUrl: '',
+ });
+
+ // …build your own fields with form.getFieldProps(), etc.
+}
+```
+
+See [React JS](./reactjs.mdx) for themes, captchas, custom renderers, and the full hook API.
+
+## File uploads
+
+Official packages handle multipart submits and File Drag & Drop via `@solspace/freeform-extensions`. You do not need the older GraphQL Base64 upload guides for new projects.
+
+## Legacy demos
+
+Older Next.js GraphQL / AJAX demos:
+
+- [Next.js + GraphQL](https://github.com/solspace/craft-freeform-demo-nextjs-graphql)
+- [Next.js + AJAX](https://github.com/solspace/craft-freeform-demo-nextjs-ajax)
+
+Recommended path for new work: this page + [Getting Started](./getting-started.mdx).
diff --git a/craft-freeform/headless/reactjs.mdx b/craft-freeform/headless/reactjs.mdx
index d8cd8dbf..68919a64 100644
--- a/craft-freeform/headless/reactjs.mdx
+++ b/craft-freeform/headless/reactjs.mdx
@@ -1,33 +1,222 @@
---
-title: React.js
+title: React JS
sidebar_position: 3
-description: Build headless forms with Freeform 5.x and React.js in Craft CMS.
+description: Build headless Freeform forms with the official React packages for Craft CMS.
---
import { Badge, BadgeGroup } from '@site/src/components/utils';
-# React JS Implementations
+# React JS
-:::warning
-Please see the [How to Render a Form](./graphql.mdx#how-to-render-a-form) guide for detailed steps for being able to render your own form in the front-end using GraphQL data and React JS.
-:::
+Use the official `@solspace/freeform-react` packages (`0.1.0`). See [Getting Started](./getting-started.mdx) for enabling the headless API.
-## GraphQL Demo
+## Install
-The below demo link shows how Freeform is implemented with [React JS](https://react.dev/) and [GraphQL](./graphql.mdx).
+```bash
+npm install @solspace/freeform-core \
+ @solspace/freeform-react \
+ @solspace/freeform-extensions \
+ @solspace/freeform-react-theme-default
+```
-:::info
-Please note that the paths in the demos are specific for the Solspace demo site and server. Please make sure your code uses paths that match your server setup.
-:::
+Import the default theme CSS once in your app entry:
+
+```tsx
+import '@solspace/freeform-react-theme-default/styles.css';
+```
+
+## Render with ``
+
+The easiest path — Freeform loads the manifest, manages state, renders fields, handles CSRF, and submits:
+
+```tsx title="ContactForm.tsx" showLineNumbers
+import { Freeform } from '@solspace/freeform-react';
+import { recommendedExtensions } from '@solspace/freeform-extensions';
+import '@solspace/freeform-react-theme-default/styles.css';
+
+export function ContactForm() {
+ return (
+ {
+ // response.success, response.submission, etc.
+ }}
+ onError={(response) => {
+ // Field / form errors from Freeform
+ }}
+ />
+ );
+}
+```
+
+| Prop | Description |
+| --- | --- |
+| `handle` | Form handle (must be allowed in `headless.forms`) |
+| `baseUrl` | Craft origin. Use `""` or your SPA origin when `/freeform` is proxied. |
+| `extensions` | Captcha / datetime / file-dnd extensions |
+| `theme` | Optional theme object (`lightTheme`, `darkTheme`, or `createTheme()`) |
+| `allowRawHtml` | Default `false`. Set `true` only if HTML/rich-text fields are trusted CMS content. |
+| `loadingFallback` / `errorFallback` | Custom loading and error UI |
+
+### Light / dark theme
+
+```tsx
+import { Freeform } from '@solspace/freeform-react';
+import {
+ darkTheme,
+ lightTheme,
+} from '@solspace/freeform-react-theme-default';
+import '@solspace/freeform-react-theme-default/styles.css';
+
+;
+// or theme={lightTheme}
+```
+
+By default the theme follows the visitor’s OS preference (`system`).
+
+## Headless control with `useFreeform()`
+
+Own the markup while Freeform still loads the form, tracks values, evaluates conditionals, and submits:
+
+```tsx title="HeadlessContactForm.tsx" showLineNumbers
+import { useFreeform } from '@solspace/freeform-react';
+import { recommendedExtensions } from '@solspace/freeform-extensions';
+
+export function HeadlessContactForm() {
+ const form = useFreeform({
+ handle: 'contact',
+ baseUrl: 'https://cms.example.com',
+ extensions: recommendedExtensions,
+ });
+
+ if (form.loading) {
+ return Loading…
;
+ }
+
+ if (form.error) {
+ return {form.error.message}
;
+ }
+
+ return (
+
+ );
+}
+```
-The below demo link shows how Freeform is implemented with [React JS](https://react.dev/) and AJAX.
+Useful helpers on the hook result:
+
+| API | Purpose |
+| --- | --- |
+| `getFieldProps(handle)` | `name`, `id`, `onChange`, `onBlur`, etc. |
+| `values` / `setValue` | Read / write field values |
+| `fieldErrors` / `formErrors` | Validation messages |
+| `isFieldVisible(handle)` | Conditional visibility |
+| `handleSubmit` / `goNext` / `goBack` | Submit and multi-page |
+
+## Captchas and advanced fields
+
+Pass `recommendedExtensions` (or a subset) so Freeform can mount captchas, Flatpickr datetime fields, and File Drag & Drop:
+
+```tsx
+import {
+ captchaExtensions,
+ datetimeExtension,
+ fileDndExtension,
+ recommendedExtensions,
+} from '@solspace/freeform-extensions';
+
+// All of the above:
+
+
+// Or pick what you need:
+
+```
+
+Configure captcha integrations in the Freeform control panel. Site keys are exposed on the form manifest; tokens are submitted automatically through `meta.captchas`.
+
+## Custom field renderers
+
+Override rendering by handle, frontend renderer key, or field type:
+
+```tsx
+
+```
+
+## Same-origin proxy (recommended)
+
+Point your Vite (or other) dev server at Craft so CSRF cookies stay same-origin:
+
+```ts title="vite.config.ts"
+export default {
+ server: {
+ proxy: {
+ '/freeform': {
+ target: 'https://cms.example.com',
+ changeOrigin: true,
+ secure: false, // local TLS only
+ },
+ },
+ },
+};
+```
+
+Then use `baseUrl=""` (or `window.location.origin`) in the browser.
+
+For Next.js, see the [Next.js](./nextjs.mdx) guide.
+
+## Security notes
+
+- Leave **`allowRawHtml`** at the default (`false`) unless HTML fields are trusted.
+- Enable a **captcha** on public forms.
+- Set **`headless.allowedOrigins`** when calling Craft cross-origin.
+- See [REST API](./rest-api.mdx) for CORS and CSRF details.
+
+## Example demo
+
+- [Freeform Headless React Demo](https://github.com/solspace/freeform-headless-react-demo) — Vite app using the official npm packages
+
+## Legacy GraphQL / AJAX demos
+
+Older demos that query Freeform via GraphQL or custom AJAX still work, but are **not** the recommended path for new projects:
:::info
Please note that the paths in the demos are specific for the Solspace demo site and server. Please make sure your code uses paths that match your server setup.
:::
-https://github.com/solspace/craft-freeform-demo-reactjs-ajax
+- [React + GraphQL demo](https://github.com/solspace/craft-freeform-demo-reactjs-graphql)
+- [React + AJAX demo](https://github.com/solspace/craft-freeform-demo-reactjs-ajax)
+
+For GraphQL field queries and mutations, see [GraphQL](./graphql.mdx).
diff --git a/craft-freeform/headless/rest-api.mdx b/craft-freeform/headless/rest-api.mdx
new file mode 100644
index 00000000..f54cbf69
--- /dev/null
+++ b/craft-freeform/headless/rest-api.mdx
@@ -0,0 +1,166 @@
+---
+title: REST API
+sidebar_position: 2
+description: Freeform headless REST API for manifests, submissions, CSRF, CORS, and file uploads in Craft CMS.
+---
+
+import { Badge, BadgeGroup } from '@site/src/components/utils';
+
+# REST API
+
+The headless REST API ships with the Freeform plugin. Official npm clients are on an independent **`0.1.0`** line ([npm org](https://www.npmjs.com/org/solspace)).
+
+Most customers should use [`@solspace/freeform-react`](./reactjs.mdx) and never call these endpoints by hand. This page is the contract reference when you build a custom client or debug requests.
+
+## Enable the API
+
+Configure this in your **Craft CMS project** (where Freeform is installed), not in your frontend repo.
+
+Edit or create `config/freeform.php` alongside Craft’s other config files (e.g. `your-craft-project/config/freeform.php`). Merge a `headless` section (keep any existing Freeform settings):
+
+```php title="config/freeform.php" showLineNumbers
+ [
+ 'enabled' => true,
+ 'allowedOrigins' => [
+ 'http://localhost:3000',
+ 'https://app.example.com',
+ ],
+ 'forms' => [
+ 'contact' => [
+ 'exposeManifest' => true,
+ 'allowSubmit' => true,
+ // Optional per-form CORS override
+ // 'allowedOrigins' => ['https://app.example.com'],
+ ],
+ ],
+ ],
+];
+```
+
+| Setting | Purpose |
+| --- | --- |
+| `headless.enabled` | Master switch. When `false`, headless routes return 404. |
+| `headless.allowedOrigins` | Global CORS allow-list (supports `*` wildcards like `https://*.example.com`). |
+| `forms.{handle}.exposeManifest` | Allow `GET` manifest for that form. |
+| `forms.{handle}.allowSubmit` | Allow `POST` submit for that form. |
+
+A config example ships with Freeform at `packages/plugin/config/headless.example.php`.
+
+## Endpoints
+
+URLs below are relative to your Craft site. Official clients resolve them with your `baseUrl`.
+
+### Form manifest
+
+```http
+GET /freeform/api/forms/{handle}/manifest
+Accept: application/json
+```
+
+Returns layout, fields, conditionals, security metadata, and submit endpoint URLs.
+
+### Submit
+
+```http
+POST /freeform/api/forms/{handle}/submit
+Content-Type: application/json
+# or multipart/form-data
+```
+
+JSON body shape (simplified):
+
+```json
+{
+ "values": {
+ "email": "jane@example.com",
+ "message": "Hello"
+ },
+ "intent": "submit",
+ "meta": {
+ "honeypot": { "name": "freeform_form_handle", "value": "" },
+ "javascriptTest": { "name": "freeform_form_handle", "value": "" },
+ "captchas": [{ "name": "g-recaptcha-response", "value": "…" }]
+ }
+}
+```
+
+| Intent | Use |
+| --- | --- |
+| `submit` | Final submit (or single-page forms) |
+| `next` / `back` | Multi-page navigation |
+| `validate` | Validate without completing |
+| `saveDraft` | Reserved — drafts are not available yet |
+
+**Multipart** submits use a `_freeform` JSON field for the payload plus file inputs, matching what `@solspace/freeform-core` sends automatically.
+
+### CSRF token
+
+```http
+GET /freeform/tokens
+Accept: application/json
+```
+
+When Craft CSRF is enabled, include the token on submit:
+
+- JSON: header `X-CSRF-Token: {value}`
+- Multipart: form field named with the Craft CSRF param
+
+Official clients fetch and attach this for you when `credentials: "include"` is used (default).
+
+### File Drag & Drop
+
+```http
+POST /freeform/api/forms/{handle}/files/{fieldHandle}
+POST /freeform/api/forms/{handle}/files/{fieldHandle}/delete
+```
+
+Used by the `file-dnd` extension. Requires CSRF and the upload token header provided by the client.
+
+### Named profiles (advanced)
+
+```http
+GET /freeform/api/manifests/{profile}/manifest?properties[eventId]=123
+POST /freeform/api/manifests/{profile}/submit
+```
+
+Profiles are explicit config entries under `headless.profiles` — never inferred from integrations. Use them for contextual manifests that need auth, signed tokens, or typed query properties.
+
+## CORS and credentials
+
+Browser apps that call Craft on another origin must:
+
+1. List that origin in `headless.allowedOrigins` (or per-form / per-profile overrides)
+2. Send requests with credentials (`credentials: "include"`) so CSRF cookies work
+
+**Recommended:** proxy `/freeform/*` through your frontend (Next.js rewrites, Vite proxy, etc.) so the browser stays same-origin.
+
+:::warning Do not use a wildcard CORS origin in production
+Set explicit origins. A misconfigured fallback to GraphQL’s `*` is unsafe for credentialed requests.
+:::
+
+## Security metadata
+
+The manifest includes `security` for honeypot, javascript test, and captcha site keys. Official clients fill `meta` automatically. For public forms, enable a captcha integration in Freeform — honeypot / JS test alone are soft signals for direct API callers.
+
+## Compatibility headers
+
+Manifests include:
+
+```json
+{
+ "schemaVersion": "1.0",
+ "pluginVersion": "5.15.19",
+ "minimumClientVersion": "0.1.0"
+}
+```
+
+`pluginVersion` matches Freeform. `minimumClientVersion` matches the npm client line (`0.1.0+`).
+
+## Next steps
+
+- [Getting Started](./getting-started.mdx) — install packages
+- [React JS](./reactjs.mdx) — `` and `useFreeform()`
+- [Next.js](./nextjs.mdx) — App Router + proxy
diff --git a/craft-freeform/headless/vuejs.mdx b/craft-freeform/headless/vuejs.mdx
index 53b1472b..27116676 100644
--- a/craft-freeform/headless/vuejs.mdx
+++ b/craft-freeform/headless/vuejs.mdx
@@ -1,6 +1,6 @@
---
title: Vue.js
-sidebar_position: 2
+sidebar_position: 5
description: Build headless forms with Freeform 5.x and Vue.js in Craft CMS.
---
@@ -8,6 +8,10 @@ import { Badge, BadgeGroup } from '@site/src/components/utils';
# Vue.js Implementations
+:::info Official Vue package — coming later
+Freeform’s first-class headless packages currently target **React / Next.js**. An official `@solspace/freeform-vue` adapter is planned. Until then, use GraphQL or custom AJAX as shown below, or call the [REST API](./rest-api.mdx) from your own Vue client.
+:::
+
:::warning
Please see the [How to Render a Form](./graphql.mdx#how-to-render-a-form) guide for detailed steps for being able to render your own form in the front-end using GraphQL data and Vue.js.
:::
diff --git a/craft-freeform/intro.mdx b/craft-freeform/intro.mdx
index 7dc50f20..6afd6a27 100644
--- a/craft-freeform/intro.mdx
+++ b/craft-freeform/intro.mdx
@@ -1377,7 +1377,7 @@ import Icons from '@site/static/icons/cards';
or useFreeform().',
icon: Icons.ReactIcon,
linkWithDescription: 'headless/reactjs',
},
{
title: 'Next.js',
- description: 'Full support for implementation Freeform with Next.js.',
+ description: 'App Router Client Components and CSRF-friendly proxy setup.',
icon: Icons.NextjsIcon,
filterIcon: true,
linkWithDescription: 'headless/nextjs',
},
{
title: 'GraphQL',
- description: 'With Freeform, you can easily query form layouts and submit form mutations using GraphQL.',
+ description: 'Query form layouts and create submissions with GraphQL mutations.',
icon: Icons.GraphqlIcon,
linkWithDescription: 'headless/graphql',
},
diff --git a/craft-freeform/setup/betas.mdx b/craft-freeform/setup/betas.mdx
index d4e29212..d8cb4667 100644
--- a/craft-freeform/setup/betas.mdx
+++ b/craft-freeform/setup/betas.mdx
@@ -10,30 +10,22 @@ import { Photo } from '@site/src/components/utils';
As part of our commitment to developing and releasing reliable and stable software, we thoroughly beta test all major and minor feature releases.
-:::info
-Freeform 5 is now available!
-:::
-
## Current Beta
-Stay tuned for the next Freeform beta!
+There is **no active Freeform plugin or npm package beta** at this time.
-If you wish to join this beta, please follow the instructions and guide below.
-
-:::danger
-While we carefully develop new features and put all of them through rigorous alpha and beta testing, we cannot guarantee that there will be no major issues in beta software. It's also possible that specific edge case scenarios may have been missed, etc. For this reason, we strongly advise you **not** to use the current beta version in production environments.
-:::
+Official headless React packages ship as **`0.1.0`** on npm — see [Headless → Getting Started](../headless/getting-started.mdx).
## Providing Feedback
We would greatly appreciate it if you are able to provide us with routine feedback throughout your testing and usage of the beta. Even if you aren't using any of the new features or changes, providing feedback allows us to get a better idea of how things are going for all kinds of websites.
-To make this even easier, we've included a Beta Feedback widget that displays in the Freeform control panel. Just click a star rating (_5/5_ to indicate if everything is going well, or less if you are experiencing any issues) and if you have anything to clarify, fill in a quick note in the text area and click submit. You can optionally include your email address, which will also help us get in touch with you to get more information about any issues and/or assist you as necessary.
+To make this even easier, we've included a Beta Feedback widget that displays in the Freeform control panel during plugin betas. Just click a star rating (_5/5_ to indicate if everything is going well, or less if you are experiencing any issues) and if you have anything to clarify, fill in a quick note in the text area and click submit. You can optionally include your email address, which will also help us get in touch with you to get more information about any issues and/or assist you as necessary.
Feel free to also just use a [Private Support Ticket](/support/) or report an issue via [GitHub Issues](https://github.com/solspace/craft-freeform/issues).
:::info
-**This widget will only display during betas.** If you wish to disable it from displaying, add `FREEFORM_DISABLE_BETA_FEEDBACK_WIDGET=1` to your `.ENV` file.
+**This widget will only display during plugin betas.** If you wish to disable it from displaying, add `FREEFORM_DISABLE_BETA_FEEDBACK_WIDGET=1` to your `.ENV` file.
:::
=24.14.0 <25"
},
"pnpm": {
"overrides": {
diff --git a/vercel.json b/vercel.json
index 6017c5c0..4a734736 100644
--- a/vercel.json
+++ b/vercel.json
@@ -1,6 +1,7 @@
{
"cleanUrls": true,
"trailingSlash": true,
+ "installCommand": "corepack enable && pnpm install",
"redirects": [
{
"destination": "/craft/freeform/v5/",