Skip to content

Comments

Add formspree-ajax#79

Open
lpssformspree wants to merge 29 commits intomainfrom
lsformspree/formspree-ajax
Open

Add formspree-ajax#79
lpssformspree wants to merge 29 commits intomainfrom
lsformspree/formspree-ajax

Conversation

@lpssformspree
Copy link

Summary

  • Add new @formspree/ajax package for vanilla JS/TS form submissions
  • Simplified API: formId + optional origin (replaces full endpoint URLs)
  • Lifecycle callbacks: onInit, onSubmit, onSuccess, onError, onFailure
  • Auto-disable/enable submit buttons during submission

Demo App

  • Vite-based example at examples/ajax-demo
  • Contact form with loading states and error handling
  • Uses environment variable for form ID configuration

API Example

import { initForm } from '@formspree/ajax';

initForm({
  formElement: '#contact-form',
  formId: 'your-form-id',
  onSuccess: ({ form }) => form.reset(),
  onError: (ctx, error) => console.log(error.getFormErrors()),
});

Test plan

Run yarn test in packages/formspree-ajax
Run demo with yarn dev in examples/ajax-demo
Submit form and verify success/error handling

lpssformspree and others added 3 commits January 31, 2026 18:48
New package for AJAX form submissions with @formspree/core as peer dependency.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add complete implementation of @formspree/ajax package, a recreation of
statickit-html using @formspree/core as the base.

Features:
- Form initialization with FormConfig (formElement, formEndpoint, callbacks)
- Lifecycle callbacks: onInit, onSubmit, onSuccess, onError, onFailure
- Dynamic endpoint support (production, staging, custom)
- Form context passed to all callbacks with form, formKey, endpoint, client
- TypeScript types with JSDoc documentation
- Submit button disable/enable during submission
- Extra data support (static or function-based)
- Debug logging support
- Default success handler with "Thank you!" replacement
- Form handle with destroy() method for cleanup

Files added:
- packages/formspree-ajax/src/form.ts: Core form handling logic
- packages/formspree-ajax/src/types.ts: TypeScript types and interfaces
- packages/formspree-ajax/test/form.test.ts: Unit tests
- examples/ajax-demo/index.html: Interactive demo with endpoint configuration

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace formEndpoint with simpler formId + optional origin config
- Add Vite-based demo app with contact form UI
- Include loading states, error handling, and form validation feedback
- Export appendExtraData from @formspree/core for extra form data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Jan 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
formspree-react-demo Ready Ready Preview, Comment Feb 20, 2026 5:50pm

Request Review

@changeset-bot
Copy link

changeset-bot bot commented Jan 31, 2026

🦋 Changeset detected

Latest commit: 694ef99

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@formspree/ajax Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Update vite (^5.0.0 → ^6.0.6) and tsup (^6.2.2 → ^8.4.0) to use
patched esbuild versions (>=0.24.2) that fix the moderate severity
vulnerability allowing any website to send requests to the dev server.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements missing features from statickit-html:
- renderErrors: auto-populate data-fs-error elements with error messages
- fields config: custom prettyName and errorMessages per field
- Customizable enable/disable/renderErrors functions

Updates ajax-demo example to demonstrate the new features with
inline error display and custom error messages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add DataAttributes constant with ERROR, FIELD, and SUBMIT_BTN
- data-fs-error: displays validation error messages for fields
- data-fs-field: sets aria-invalid="true" on inputs with errors
- data-fs-submit-btn: auto-disable buttons during form submission
- Update ajax-demo to use new data attributes and remove HTML required

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Removed static error styles from index.html
- Added a function to inject default error styles into the document head on form initialization
- Ensured styles are only injected once per page load

This change enhances the flexibility of styling error messages in forms.
lpssformspree and others added 2 commits February 7, 2026 17:33
Move message rendering logic (success/error) from the demo into the
package as default behavior, following the existing renderErrors pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Simplify global API to accept a single config object instead of
  formspree('form', 'init', config) dispatch pattern
- Add data-fs-message for declarative form-level success/error messages
- Add renderMessage callback and defaultRenderMessage implementation
- Inject default styles for data-fs-error, data-fs-field, and data-fs-message
- Update demos to use Formspree brand colors and simplified API
- Update tests for new global API signature

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Simplified error message handling by removing custom error messages and pretty names from the fields configuration.
- Updated error rendering to display only form-level errors, with inline field errors shown via data attributes.
- Removed unused types and interfaces related to error messages and field configurations from the codebase.
- Adjusted tests to reflect changes in error message expectations.

This refactor streamlines the form error handling process and reduces complexity in the configuration options.
… spinner functionality

- Added new data-fs-field attribute to input elements for better error handling.
- Removed unused loading spinner styles and integrated a new spinner implementation in the form submission process.
- Updated form submission logic to disable buttons and show a spinner during submission.
- Enhanced tests to verify spinner visibility and aria-invalid attribute handling for form fields.

These changes streamline the user experience during form submissions and improve accessibility features.
- Updated README to correct spelling of "JavaScript" and reorganize package information.
- Introduced `@formspree/ajax` package with installation instructions and usage examples for vanilla JavaScript form handling.
- Improved extra data handling in form submissions to support both synchronous and asynchronous functions.
- Enhanced tests to validate the inclusion of static and dynamic extra data in submissions, as well as message rendering for success and error states.

These changes improve documentation clarity and expand the functionality of the AJAX library for better user experience.
…nsistency

- Renamed `renderErrors` to `renderFieldErrors` and `renderMessage` to `renderFormMessage` for better clarity in their purposes.
- Updated the form submission logic to utilize the new rendering functions, ensuring field-level and form-level errors are handled appropriately.
- Enhanced documentation in the README and types to reflect the changes in error handling and rendering functions.
- Adjusted tests to verify the new rendering behavior and ensure proper functionality.

These changes improve the readability and maintainability of the error handling process in the AJAX library.
- Replaced `data-fs-message` with `data-fs-success` and `data-fs-error` attributes for clearer distinction between success and error messages.
- Updated HTML examples in the demo to reflect the new message handling attributes.
- Refactored rendering functions to manage visibility and content of success and error messages more effectively.
- Enhanced documentation in the README to clarify the usage of new attributes and their behavior.
- Adjusted tests to verify the correct rendering of success and error messages based on the new implementation.

These changes improve the user experience by providing clearer feedback during form submissions.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new @formspree/ajax package for vanilla JavaScript/TypeScript form submissions without requiring a framework. The implementation provides both ESM/CJS module support and a global script tag API, with declarative HTML data attributes for error handling and form state management.

Changes:

  • Added new @formspree/ajax package with lifecycle callbacks (onInit, onSubmit, onSuccess, onError, onFailure)
  • Created Vite-based demo application showcasing both ESM and script tag usage patterns
  • Updated turbo.json from deprecated "pipeline" to "tasks" configuration

Reviewed changes

Copilot reviewed 38 out of 40 changed files in this pull request and generated no comments.

Show a summary per file
File Description
turbo.json Updated Turborepo configuration to use "tasks" instead of deprecated "pipeline"
packages/formspree-ajax/* New package implementation including types, form handling, utilities, and test suites
examples/ajax-demo/* Demo application with contact form examples using both ESM and global script approaches
package.json Updated tsup to v8.4.0 and added packageManager field
README.md Documentation updates for new ajax package and installation instructions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Add command dispatch to global API: formspree('initForm', config)
- Split renderFormMessage into renderSuccess and renderFormError
- Rename demo files: index-packages.html and index-cdn.html
- Extract shared CSS into styles.css
- Update placeholder messages to realistic copy
- Keep form HTML consistent between both demos
- Add Larissa Oliveira to contributors
- Fix install instructions (core is a transitive dep)
- Replace real form ID with YOUR_FORM_ID in CDN demo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move disable/clear calls before async data resolution to prevent duplicate
submissions when ExtraData contains async functions. Add per-form submitting
guard to block concurrent handleSubmit calls. Wrap queue flush loop in
try-catch so one failing form doesn't prevent remaining forms from initializing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
README.md Outdated
};
formspree('initForm', { formElement: '#my-form', formId: 'YOUR_FORM_ID' });
</script>
<script src="https://unpkg.com/@formspree/ajax@1/dist/global.js" defer></script>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any way to make this cleaner? This is a pretty ugly script URL. Ideally it would be something like https://unpkg.com/@formspree/ajax@1.0.0

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might be able to.. I'll check on that

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colevscode Turns out the "unpkg" field in package.json already points to dist/global.js, so unpkg resolves it automatically. I’ve updated all references to use the shorter https://unpkg.com/@formspree/ajax@1 — so no explicit path needed.

Copy link
Member

@colevscode colevscode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty much good to go. I want to look at how/where it's packaged (what file path) and also need to update NPM permissions

@colevscode
Copy link
Member

@krharsh17 please review this. We're likely want to write up some tutorials and replace some of our example ajax code with this library

The "unpkg" field in package.json already points to dist/global.js,
so the explicit path is unnecessary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants