# JavaScript (AJAX) でフォームを送信する

> Formspree Docs · フォームの作成 · 2026年3月23日

#### 利用可能なプラン: すべてのプラン

[`@formspree/ajax`](https://www.npmjs.com/package/@formspree/ajax) を使用すると、独自の `fetch`、Axios、または jQuery の送信ロジックを記述せずに、プレーンな JavaScript で Formspree フォームを送信できます。

このライブラリは標準的な HTML フォームと連携し、データ属性または小さな JavaScript API を通じた宣言的なフォーム処理を追加します。フォームの送信、ローディング状態、バリデーションエラー、成功メッセージを自動的に処理します。

## 仕組み

`@formspree/ajax` はフォームをワイヤーアップするための宣言的な方法を提供します。送信イベントを手動でリッスンして独自のリクエスト処理を記述する代わりに、フォームをデータ属性でマークアップし、Formspree のフォーム ID で初期化します。

デフォルトでは、このライブラリが以下を処理します：

-   フォームの送信
-   送信ボタンのローディング状態
-   フィールドレベルのバリデーションエラー
-   フォームレベルのエラー
-   成功メッセージ
-   `aria-invalid="true"` による無効フィールドの状態

プロジェクトへの実装方法は以下のとおりです：

### ステップ 1: プロジェクトに @formspree/ajax を設定する

`@formspree/ajax` は設定によって 2 つの方法で使用できます：

-   バンドラーを使用する場合（npm/yarn 経由の ESM）
-   バンドラーを使用しない場合（script タグ/CDN）

#### オプション 1: バンドラーを使用する場合（ESM）

ライブラリをインストールします：

```bash
npm install @formspree/ajax   # via npm, or
yarn add @formspree/ajax      # via yarn
```

そして、JavaScript でフォームを初期化します：

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

initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',
});
```

HTML フォーム要素の ID が `formElement` プロパティに渡した ID と一致することを確認してください。また、`YOUR_FORM_ID` を Formspree ダッシュボードで取得したフォーム ID に置き換えてください。

#### オプション 2: script タグを使用する場合（ビルドステップなし）

バンドラーを使用していない場合は、閉じタグ `</body>` の前にこのスニペットを追加します：

```html
<script>
  window.formspree =
    window.formspree ||
    function () {
      (formspree.q = formspree.q || []).push(arguments);
    };
  formspree(
    'initForm', 
    { formElement: '#contact-form', formId: 'YOUR_FORM_ID' }
  );
</script>
<script src="https://unpkg.com/@formspree/ajax@1" defer></script>
```

最初のオプションと同様に、HTML フォーム要素の ID が `formElement` プロパティに渡した ID と一致することを確認してください。また、`YOUR_FORM_ID` を Formspree ダッシュボードで取得したフォーム ID に置き換えてください。

### ステップ 2: フォームを構築する

プロジェクトに `@formspree/ajax` を設定したら、次のようにフォームを作成できます：

```html
<div data-fs-success></div>
<div data-fs-error></div>

<form id="contact-form">
  <label for="email">Email</label>
  <input type="email" id="email" name="email" data-fs-field />
  <span data-fs-error="email"></span>

  <button type="submit" data-fs-submit-btn>Send</button>
</form>
```

> フォームの `id` 属性の値が、前のステップの `initForm` 呼び出しで `formId` として渡した ID と一致することを再度確認してください。

ライブラリはフォームを自動的に Formspree に送信し、リクエスト中は送信ボタンを無効化し、バリデーションエラーを表示し、成功メッセージを表示します。

## データ属性

`@formspree/ajax` ライブラリには、追加の JavaScript なしにフォームの動作を制御できる属性が含まれています。

### `data-fs-error="fieldName"`

フィールドレベルのバリデーションエラーを表示するには、`<span>` または `<div>` にこれを使用します。

```html
<span data-fs-error="email"></span>
```

要素が空の場合、Formspree は API のエラーメッセージを挿入します。要素に既にコンテンツが含まれている場合は、そのコンテンツが表示または非表示になります。

### `data-fs-error`

値なしで使用すると、フォームレベルのエラーを表示します。

```html
<div data-fs-error></div>
```

これは、特定のフィールドに属さない一般的な送信エラーに役立ちます。

### `data-fs-success`

送信後に成功メッセージを表示するには、これを使用します。

```html
<div data-fs-success></div>
```

要素が空の場合、デフォルトのメッセージが表示されます。既にコンテンツが含まれている場合は、そのコンテンツが使用されます。

### `data-fs-field`

バリデーションが失敗した際に `aria-invalid="true"` を受け取るべきフォームフィールドにこれを使用します。

```html
<input type="email" name="email" data-fs-field />
```

ライブラリは要素の `name` 属性からフィールド名を読み取ります。

### `data-fs-submit-btn`

送信ボタンにこれを使用すると、送信中は無効化され、送信後に再び有効化されます。

```html
<button type="submit" data-fs-submit-btn>Send</button>
```

## デフォルトの動作

何もオーバーライドしない場合、ライブラリは合理的なデフォルトを提供します：

-   フォームの送信中は送信ボタンが無効化されます。
-   フィールドエラーは対応する `data-fs-error="fieldName"` 要素内に表示されます。
-   無効なフィールドには `aria-invalid="true"` が設定されます。
-   成功メッセージは `data-fs-success` 要素に表示されます。
-   フォームレベルのエラーメッセージは `data-fs-error` 要素に表示されます。
-   `data-fs-success` 要素がなく、カスタムの `onSuccess` ハンドラーもない場合、フォームは「Thank you!」メッセージに置き換えられます。
-   `data-fs-success` 要素があり、カスタムの `onSuccess` ハンドラーがない場合、送信成功後にフォームがリセットされます。
-   基本的なデフォルトスタイルが自動的に注入されます。

## 高度な設定

ライブラリにはフォームの動作と外観をさらにカスタマイズする方法も提供されています。

### すべての送信に追加データを付与する

`data` オプションを使用して、すべてのフォーム送信に追加の値を追加できます。値には以下が使用できます：

-   静的な文字列
-   同期関数
-   非同期関数

`undefined` の値はスキップされます。使用方法は以下のとおりです：

```javascript
initForm({
  formElement: '#my-form',
  formId: 'YOUR_FORM_ID',

  // This data will be added to every submission
  data: {
    source: 'landing-page',
    referrer: () => document.referrer || undefined,
    sessionId: async () => await fetchSessionId(),
  },
});
```

これは、HTML に隠し入力を追加せずに、キャンペーン名、参照元、またはセッション ID などのメタデータを添付するのに便利です。

### ライフサイクルコールバック

送信ライフサイクルのさまざまなステージにフックすることができます。

```javascript
initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',

  // Called when the form is initialized
  onInit: (context) => {
    console.log('Form initialized');
  },

  // Called before submission is sent.
  onSubmit: (context) => {
    console.log('Submitting form');
  },

  // Called on successful submission.
  onSuccess: (context, result) => {
    console.log('Submission succeeded', result);
  },

  // Called if validation errors are received from Formspree
  onError: (context, error) => {
    console.log('Validation error', error);
  },

  // Called if unexpected errors are received (e.g., network failure).
  onFailure: (context, error) => {
    console.log('Unexpected error', error);
  },
});
```

`context` オブジェクトには、現在のフォーム（`HTMLFormElement`）、エンドポイントの詳細、クライアント、および `initForm` に渡した設定オブジェクトが含まれます。

これらのコールバックは以下の用途に使用できます：

-   イベントのトラッキング（アナリティクス、コンバージョン、離脱）
-   カスタム UI の表示（スピナー、トースト、バナー）
-   送信成功後のリダイレクト
-   リクエストとエラーのログ記録やデバッグ
-   バリデーションまたはフォームレベルエラーのカスタム処理
-   送信前後のサイドエフェクトの実行（状態の保存、ワークフローのトリガーなど）

### カスタムレンダリング

`initForm()` でカスタムレンダリングメソッドを提供することで、デフォルトの UI 動作をオーバーライドできます。これはローディング状態、エラー、成功メッセージの表示を完全に制御したい場合に便利です。

```javascript
initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',

  enable: (context) => {},
  disable: (context) => {},
  renderFieldErrors: (context, error) => {},
  renderSuccess: (context, message) => {},
  renderFormError: (context, message) => {},
});
```

#### 利用可能なメソッド

  
| メソッド | 実行タイミング | 主な用途 |
| --- | --- | --- |
| `disable(context)` | 送信開始時 | ローディング状態の追加、ボタン/入力の無効化 |
| `enable(context)` | 送信完了後 | スピナーの削除、UI の再有効化 |
| `renderFieldErrors(context, error)` | バリデーションエラー時 | カスタムエラー UI、グループ化されたエラー、トーストメッセージ |
| `renderSuccess(context, message)` | 送信成功時 | フォームの置き換え、トーストの表示、リダイレクト |
| `renderFormError(context, message)` | フォームレベルエラー時 | エラーバナー、アラート、集中型メッセージング |

使用方法は以下のとおりです：

```javascript
initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',

  disable: ({ form }) => form.classList.add('loading'),
  enable: ({ form }) => form.classList.remove('loading'),

  renderSuccess: ({ form }, message) => {
    form.innerHTML = `<p>${message}</p>`;
  },
});
```

### スタイリング

ライブラリにはエラー、無効フィールド、成功メッセージのデフォルトスタイルが含まれています。独自の CSS でオーバーライドすることができます。

```css
[data-fs-error] {
  color: #dc3455;
}

[data-fs-field][aria-invalid='true'] {
  border-color: #dc3455;
}

[data-fs-success][data-fs-active] {
  background: #de4dda;
}

[data-fs-error=''][data-fs-active] {
  background: #f87dda;
  color: #72c124;
}
```

### クリーンアップ

`initForm()` は `destroy()` メソッドを持つハンドルを返します。後でフォームの動作をクリーンアップする必要がある場合に使用できます。

```javascript
const handle = initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',
});

// Clean up when needed
handle.destroy();
```

## ESM の完全な例

以下は、プレーンな HTML フォームと `@formspree/ajax` をバンドラーで使用した完全な例です。まず、Formspree のフォーム ID でフォームを初期化します：

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

initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',
});
```

次に、上記で説明したデータ属性を使用して HTML フォームを作成します：

```html
<div data-fs-success></div>
<div data-fs-error></div>

<form id="contact-form">
  <label for="email">Email</label>
  <input type="email" id="email" name="email" data-fs-field />
  <span data-fs-error="email"></span>

  <label for="message">Message</label>
  <textarea id="message" name="message" data-fs-field></textarea>
  <span data-fs-error="message"></span>

  <button type="submit" data-fs-submit-btn>Send</button>
</form>
```

## script タグの例

ビルドステップなしでライブラリを使用したい場合は、ブラウザで直接初期化できます：

```html
<div data-fs-success></div>
<div data-fs-error></div>

<form id="my-form">
  <label for="email">Email</label>
  <input type="email" id="email" name="email" data-fs-field />
  <span data-fs-error="email"></span>

  <label for="message">Message</label>
  <textarea id="message" name="message" data-fs-field></textarea>
  <span data-fs-error="message"></span>

  <button type="submit" data-fs-submit-btn>Submit</button>
</form>

<script>
  window.formspree =
    window.formspree ||
    function () {
      (formspree.q = formspree.q || []).push(arguments);
    };

  formspree('initForm', {
    formElement: '#my-form',
    formId: 'YOUR_FORM_ID',
  });
</script>
<script src="https://unpkg.com/@formspree/ajax@1" defer></script>
```

## 手動 AJAX コードからの移行

以前にカスタムの `fetch`、Axios、または jQuery コードでフォームを送信していた場合、`@formspree/ajax` はよりシンプルな代替手段を提供します。以下を手動で行う代わりに：

-   送信イベントのリッスン
-   フォームデータのシリアライズ
-   リクエストの送信
-   バリデーションエラーの解析
-   成功および失敗状態の DOM 更新

ライブラリを一度初期化するだけで、それらの処理を任せることができます。

## フレームワークに関する注意

このライブラリはバニラ JavaScript と標準的な HTML フォーム向けに設計されています。React を使用している場合は、代わりに[React ライブラリ](/articles/working-with-react/the-formspree-react-library/)をご確認ください。
