@apostrophecms/form

中文文档
1.5.6发布于 2026/10/15MITCommonJS近 30 天下载 2241

Build forms for ApostropheCMS in a simple user interface.

原始使用文档
文档目录30 节
  1. Why Form Builder?
  2. Table of Contents
  3. Installation
  4. Usage
  5. Module Configuration
  6. How It Works
  7. Adding Form Widget to Areas
  8. Editor Workflow
  9. Configuration
  10. Main Module Options
  11. Available Field Types
  12. Handling Submissions
  13. Database Storage
  14. Email Notifications
  15. Server-Side Events
  16. Browser Events
  17. reCAPTCHA Integration
  18. Configuration Options
  19. Styling
  20. Custom CSS Classes
  21. Field-Specific Options
  22. Select Field
  23. File Upload Field
  24. Custom Field Validation
  25. Extending Collectors with the Super Pattern
  26. Example: Minimum Word Count Validation
  27. Error Handling
  28. Use Cases
  29. 💎 Ready for More?
  30. 🚀 Pro Features for Forms
ApostropheCMS logo

Form Builder for ApostropheCMS

Let content teams build and manage forms without developer intervention. Editors can create contact forms, surveys, applications, and registrations directly in the CMS, then place them anywhere on your site. Forms automatically handle submissions, email notifications, validation, and spam protection.

Why Form Builder?

  • No-Code Form Creation: Editors build forms through configurable field widgets—no tickets to developers
  • Automatic Data Collection: Submissions saved to MongoDB with optional email notifications
  • 🛡️ Built-in Security: reCAPTCHA v3 integration and validation prevent spam
  • Design Freedom: Custom CSS classes and styling hooks for brand consistency
  • Developer-Friendly: Event hooks, custom validators, and extensible field types
  • Email Ready: Route submissions to multiple recipients automatically

Table of Contents

Installation

npm install @apostrophecms/form

Usage

Module Configuration

Configure the form modules in your app.js file:

import apostrophe from 'apostrophe';

apostrophe({
  root: import.meta,
  shortName: 'my-project',
  modules: {
    // Main form module (must come first)
    '@apostrophecms/form': {},
    // Form widget for adding forms to areas
    '@apostrophecms/form-widget': {},
    // Field widgets (include only the types you need)
    '@apostrophecms/form-text-field-widget': {},
    '@apostrophecms/form-textarea-field-widget': {},
    '@apostrophecms/form-select-field-widget': {},
    '@apostrophecms/form-radio-field-widget': {},
    '@apostrophecms/form-file-field-widget': {},
    '@apostrophecms/form-checkboxes-field-widget': {},
    '@apostrophecms/form-boolean-field-widget': {},
    '@apostrophecms/form-conditional-widget': {},
    '@apostrophecms/form-divider-widget': {},
    '@apostrophecms/form-group-widget': {}
  }
});

Module order matters: @apostrophecms/form must appear before the widget modules. Include only the field types you want editors to use.

How It Works

The @apostrophecms/form module creates a new piece-type called "Forms" in your CMS. This means forms are content that editors create once and can reuse across multiple pages—just like blog posts or products. Create a "Contact Form" once, then place it on your contact page, footer, and sidebar using the form widget.

Adding Form Widget to Areas

To let editors add forms to a page or piece-type, include the form widget in an area:

// modules/contact-page/index.js
export default {
  extend: '@apostrophecms/piece-page-type',
  options: {
    label: 'Contact Page'
  },
  fields: {
    add: {
      contactForm: {
        type: 'area',
        options: {
          max: 1,
          widgets: {
            '@apostrophecms/form': {}
          }
        }
      }
    },
    group: {
      basics: {
        fields: ['contactForm']
      }
    }
  }
};

Editor Workflow

Once configured, editors can create and manage forms:

  1. Create a form: Click "Forms" in the admin bar and create a new form (e.g., "Contact Form")
  2. Build the form: Add field widgets (text fields, email, checkboxes, etc.) and configure options
  3. Configure submission handling: Set up email notifications and confirmation messages in the "After-Submission" tab
  4. Place the form: Edit any page with a form area, add the form widget, and select your created form

Editors can now create and manage forms independently.

Configuration

Main Module Options

Configure @apostrophecms/form with these options:

PropertyTypeDescription
disableOptionalLabelBooleanRemoves "(Optional)" text from optional fields. Default: false
formWidgetsObjectWidget configuration for allowed field types in forms
saveSubmissionsBooleanSet to false to prevent saving submissions to MongoDB. Default: true
emailSubmissionsBooleanSet to false to hide email notification fields. Default: true
recaptchaSecretStringSecret key from reCAPTCHA site configuration
recaptchaSiteStringSite key for reCAPTCHA integration
classPrefixStringNamespace for CSS classes on form elements
uploadLimitsObjectLimits for multipart form submissions, merged with the defaults: fileSize (bytes per file, default: the maxSize option of @apostrophecms/attachment if set, otherwise 20MB), files (default: 20), fields (default: 50) and fieldSize (bytes per non-file field, default: 1MB). Files are only accepted for forms that have a matching file field

Available Field Types

The formWidgets option controls which widgets editors can use when building forms. Configure this in your project-level /modules/@apostrophecms/form/index.js file to override the built-in defaults. This is a global setting that applies to all forms in your project.

Default configuration:

// modules/@apostrophecms/form/index.js
export default {
  options: {
    formWidgets: {
      '@apostrophecms/form-text-field': {},
      '@apostrophecms/form-textarea-field': {},
      '@apostrophecms/form-boolean-field': {},
      '@apostrophecms/form-select-field': {},
      '@apostrophecms/form-radio-field': {},
      '@apostrophecms/form-checkboxes-field': {},
      '@apostrophecms/form-conditional': {},
      '@apostrophecms/form-divider': {},
      '@apostrophecms/rich-text': {
        toolbar: [
          'styles', 'bold', 'italic', 'link',
          'orderedList', 'bulletList'
        ]
      }
    }
  }
};

The rich text widget allows editors to add instructions within forms. Any widget type can be included in this configuration.

Need different field types for different forms? The formWidgets option is global and cannot be set per-area or per-page. If you need separate sets of allowed fields (for example, a simple contact form vs. a detailed application form), extend the @apostrophecms/form module to create a second form piece-type with its own formWidgets configuration. However, without additional controls, all editors can use both form types. Use @apostrophecms-pro/advanced-permission to restrict which user groups can create and manage each form type—ensuring junior editors only access basic forms while senior staff can use advanced forms. Learn more about Pro features.

Handling Submissions

Database Storage

Submissions are automatically saved to the aposFormSubmissions MongoDB collection. To disable database storage:

// modules/@apostrophecms/form/index.js
export default {
  options: {
    saveSubmissions: false
  }
};

Email Notifications

If @apostrophecms/email is configured, forms can automatically email submissions to multiple recipients. In the form editor, navigate to the "After-Submission" tab and enter comma-separated email addresses in the "Email Address(es) for Results" field.

To hide email notification fields:

// modules/@apostrophecms/form/index.js
export default {
  options: {
    emailSubmissions: false
  }
};

📧 Email Configuration: To send form submissions via email, you must first configure the @apostrophecms/email module. See the email configuration guide for setup instructions. Forms can still save submissions to the database without email configuration.

Server-Side Events

Form submissions trigger events you can handle in your code for custom processing, integrations, or modifying submission data. For example, you could send submissions to an external CRM, add server-side metadata like query parameters, or trigger custom workflows.

submission event - Fires on every form submission:

// modules/@apostrophecms/form/index.js
export default {
  handlers(self) {
    return {
      'submission': {
        async handleSubmission(req, form, submission) {
          // Your custom logic here
          console.log('Form submitted:', form.title);
          console.log('Data:', submission);
        }
      }
    };
  }
};

beforeSaveSubmission event - Fires before saving the info.submission to the database (if enabled):

// modules/@apostrophecms/form/index.js
export default {
  handlers(self) {
    return {
      'beforeSaveSubmission': {
        async modifySubmission(req, info) {
          // Modify info.submission before it's saved
          info.submission.processedAt = new Date();
        }
      }
    };
  }
};

Event handler arguments:

EventArgumentsDescription
submissionreq, form, submissionRequest object, form document, submission data
beforeSaveSubmissionreq, infoRequest object, object with form, data, and submission properties

Browser Events

The form module emits browser events on the body element after a submission attempt. You can listen for these to add custom client-side feedback or analytics.

Success Event

@apostrophecms/form:submission-form Fires when a submission is successfully processed. The event detail includes a form property.

document.body.addEventListener('@apostrophecms/form:submission-form', e => {
  // e.detail.form contains the form element/config
  console.log('Form submitted successfully:', e.detail.form);

  // Example: show a toast notification
  apos.notify('✅ Thanks for your submission!', { type: 'success' });

  // Example: send analytics event
  gtag('event', 'form_submission', {
    formTitle: e.detail.form.title || 'Untitled Form'
  });
});

Failure Event

@apostrophecms/form:submission-failed Fires when a submission fails due to validation errors, spam protection, or server issues. The event detail includes a formError property.

document.body.addEventListener('@apostrophecms/form:submission-failed', e => {
  // e.detail.formError contains the error info
  console.error('Form submission failed:', e.detail.formError);

  // Example: show a custom error banner
  apos.notify('⚠️ Something went wrong. Please try again.', { type: 'danger' });

  // Example: track failed attempts
  gtag('event', 'form_submission_failed', {
    error: e.detail.formError.message || 'Unknown'
  });
});

Use Cases

  • Replace the default "thank you" UI with a custom success message
  • Push events into Google Tag Manager, Segment, or other analytics
  • Redirect or scroll the page after a successful submission
  • Display tailored error messages on failure

Note: Forms already support built-in after-submission messages (thankYouHeading, thankYouBody) and inline error handling. You only need these browser events if you want extra client-side behavior beyond what the module provides out of the box.

reCAPTCHA Integration

Protect forms from spam with Google reCAPTCHA v3. Set up reCAPTCHA at google.com/recaptcha using version 3, then configure your site and secret keys.

Configuration Options

Option 1: Hard-code in module configuration

// modules/@apostrophecms/form/index.js
export default {
  options: {
    recaptchaSecret: 'YOUR_SECRET_KEY',
    recaptchaSite: 'YOUR_SITE_KEY'
  }
};

Option 2: Allow editors to configure in UI

If you don't hard-code both keys, a global settings UI appears where admins can enter them. Once configured, each form has a checkbox to enable reCAPTCHA independently.

Styling

Custom CSS Classes

Add your own class prefix to form elements for complete styling control:

// modules/@apostrophecms/form/index.js
export default {
  options: {
    classPrefix: 'my-form'
  }
};

This generates BEM-style classes like my-form__input, my-form__label, and my-form__error on form elements.

For teams who prefer visual design tools, Apostrophe's built-in global styles let editors adjust CSS properties from the admin interface without writing code.

Field-Specific Options

Select Field

The select field widget supports multiple selections:

// modules/@apostrophecms/form-select-field-widget/index.js
export default {
  options: {
    allowMultiple: true  // Default: false
  }
};

When enabled, two additional fields appear in the widget schema:

PropertyTypeDescriptionDefault
allowMultipleBooleanEnable multiple selections.false
sizeIntegerNumber of visible options. Set to 0 to use the default compact dropdown; set to 2 or higher to render a listbox showing that many options at once.0

File Upload Field

⚠️ Security Warning: File upload fields allow any visitor to upload files to your server, creating potential risks for storage abuse and malicious uploads. This widget is not included by default—you must explicitly enable it.

Where to implement security measures:

  1. Storage provider level (AWS S3, Google Cloud Storage, Azure Blob):

    • Configure file type restrictions, size limits, and lifecycle policies in your provider's console
    • Set up bucket quotas and alerts for unusual upload patterns
    • See your provider's documentation for content validation features
  2. ApostropheCMS attachment module (modules/@apostrophecms/attachment/index.js):

    export default {
      options: {
        // Restrict file types (extension allowlist)
        fileGroups: [
          {
            name: 'images',
            label: 'Images',
            extensions: [ 'jpg', 'jpeg', 'png', 'gif', 'webp' ],
            extensionMaps: { jpeg: 'jpg' }
          },
          {
            name: 'office',
            label: 'Documents',
            extensions: [ 'pdf', 'doc', 'docx', 'xls', 'xlsx' ],
            extensionMaps: {}
          }
        ],
        // Set maximum file size (in bytes)
        maxSize: 10485760  // 10MB
      }
    };
    

    See the attachment module documentation for complete configuration options.

  3. Form submission handler (for additional validation):

    // modules/@apostrophecms/form/index.js
    export default {
      handlers(self) {
        return {
          'beforeSaveSubmission': {
            async validateFiles(req, info) {
              // Add custom file validation logic here
              // Access uploaded files via info.data
            }
          }
        };
      }
    };
    
  4. Spam protection: Enable reCAPTCHA v3 (see reCAPTCHA Integration section)

Files are stored in your configured attachment storage (local uploads or cloud bucket). Form submissions save attachment URLs, not the files themselves.

Multiple file uploads: Like the select field, the file field widget supports an allowMultiple option:

// modules/@apostrophecms/form-file-field-widget/index.js
export default {
  options: {
    allowMultiple: true  // Default: false
  }
};

When enabled, users can select and upload multiple files in a single form submission.

Custom Field Validation

Need business-specific rules like minimum word counts, format requirements, or cross-field dependencies? Extend the built-in field collectors to add custom validation logic before submission. This runs client-side for immediate feedback without server round-trips.

Each field returns its value from a collector function located on the apos.aposForm.collectors array in the browser. You can extend these collector functions to adjust the value or do additional validation before the form posts to the server. Collector functions can be written as asynchronous functions if needed.

Collector functions take the widget element as an argument and return a response object on a successful submission. The response object properties are:

PropertyDescription
fieldThe field element's name attribute (identical to the field widget's name property)
valueThe field value

Extending Collectors with the Super Pattern

These functions can be extended for project-level validation using the super pattern. This involves:

  1. Assigning the original function to a variable
  2. Creating a new function that uses the original one, adds functionality, and returns an identically structured response
  3. Assigning the new function to the original function property

Example: Minimum Word Count Validation

// modules/@apostrophecms/form-textarea-field-widget/ui/src/index.js

export default () => {
  const TEXTAREA_WIDGET = '@apostrophecms/form-textarea-field';

  // 1️⃣ Store the original collector function on `superCollector`.
  const superCollector = apos.aposForm.collectors[TEXTAREA_WIDGET].collector;

  // 2️⃣ Create a new collector function that accepts the same widget element
  // parameter.
  function newCollector(el) {
    // Get the response from the original collector.
    const response = superCollector(el);

    if (response.value && response.value.split(' ').length < 10) {
      // Throwing an object if there are fewer than ten words.
      throw {
        field: response.field,
        message: 'Write at least 10 words'
      };
    } else {
      // Returning the original response if everything is okay.
      return response;
    }
  }

  // 3️⃣ Assign our new collector to the original property.
  apos.aposForm.collectors[TEXTAREA_WIDGET].collector = newCollector;
};

Error Handling

If you want to indicate an error on the field, throw an object with the following values (as shown above):

PropertyDescription
fieldThe field element's name attribute (identical to the field widget's name property)
messageA string to display on the field as an error message

Use Cases

Contact Forms: Let teams create department-specific contact forms without developer involvement.

Lead Generation: Build conversion-optimized forms with conditional fields and reCAPTCHA protection.

Event Registration: Collect attendee information with file uploads for documents or photos.

User Feedback: Create surveys and feedback forms that route to appropriate team members.

Job Applications: Accept resumes and application materials with validation and email routing.

💎 Ready for More?

The open-source form builder provides powerful form creation capabilities, but enterprise teams often need advanced control and workflow features. ApostropheCMS Pro extends form functionality with professional-grade features:

🚀 Pro Features for Forms

  • 🔐 Advanced Permissions - Control which teams can create, edit, and manage specific form types. Restrict access to sensitive forms like HR applications or customer data collection. Perfect for multi-team organizations that need different form capabilities for different departments.

  • 🌍 Automated Translation - Automatically translate forms and confirmation messages into multiple languages with AI-powered translation services (DeepL, Google Translate, Azure). Deploy multilingual forms without manual translation work.

  • 📄 Document Management - Version control for forms with complete audit trails. Track changes to form fields, restore previous versions, and maintain compliance with form modification history.

Create an account on Apostrophe Workspaces and upgrade to ApostropheCMS Pro or contact our team to learn about Pro licensing and access enterprise features that enhance form management, compliance, and team collaboration.


Made with ❤️ by the ApostropheCMS team. Found this useful? Give us a star on GitHub! ⭐

版本与发布记录

@apostrophecms/form 共发布 19 个版本,首次发布于 2021/10/15;过去 12 个月发布了 4 个版本。

版本发布日期距今
1.5.6latest2026/10/1524 天前
1.5.52026/10/011 个月前
1.5.42026/07/113 个月前
1.5.32026/02/198 个月前
1.5.22025/10/311 年前
1.5.12025/07/101.3 年前

其他发布通道:beta → 1.0.0-beta.1。

关于 @apostrophecms/form 的常见问题

@apostrophecms/form 是什么?

Build forms for ApostropheCMS in a simple user interface.

如何安装 @apostrophecms/form?

在项目目录运行 npm install @apostrophecms/form,或使用 pnpm add / yarn add / bun add。

@apostrophecms/form 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/apostrophecms__form 是否存在。

@apostrophecms/form 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@apostrophecms/form 可以商用吗?

@apostrophecms/form 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@apostrophecms/form 的下载量有多少?

根据 npm 官方下载统计,@apostrophecms/form 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,241 次,日均约 75 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@apostrophecms/form 还在维护吗?

最新版本 1.5.6 发布于 2026/10/15(24 天前);至今共发布 19 个版本,其中过去 12 个月发布了 4 个;首次发布于 2021/10/15。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。