For the complete documentation index, see llms.txt. This page is also available as Markdown.

Installation

The Symfony UX Initiative enables high-interaction applications directly from Twig templates without writing custom JavaScript. The WebAuthn Stimulus Controller makes implementing passwordless authentication as simple as adding a few Twig functions to your forms.

Prerequisites

Before installing the Stimulus Controller, you need:

  1. Symfony UX configured — follow the official Symfony UX documentation

  2. WebAuthn Bundle installed — see Symfony Bundle Installation

Installation

Since v5.3.0 the Stimulus controllers are published on npm as @web-auth/webauthn-stimulus. The npm package is the canonical and only maintained source going forward — the legacy web-auth/webauthn-stimulus Composer package is deprecated and will be removed in 6.0.0.

1. Pin the package in your importmap

With Symfony AssetMapper:

php bin/console importmap:require @web-auth/webauthn-stimulus

With Webpack Encore, Vite, esbuild or any other bundler:

npm install @web-auth/webauthn-stimulus

The package depends on @hotwired/stimulus and @simplewebauthn/browser, which are pulled in automatically by AssetMapper or your bundler.

2. Register the controllers in your Stimulus app

Import the controllers from the package entry point and register them on your Stimulus Application. Use the same ---separated identifiers that stimulus_controller('@web-auth/webauthn-stimulus/...') produces, so the existing Twig helpers keep working unchanged:

Why these identifiers? stimulus_controller('@vendor/pkg/ctrl') simply transforms the name to a flat string by stripping the leading @ and turning / into --. So stimulus_controller('@web-auth/webauthn-stimulus/authentication') renders data-controller="web-auth--webauthn-stimulus--authentication" — the same identifier you registered in JS. Existing Twig templates that use the @-prefixed form keep working without changes.

The exact location of your Stimulus bootstrap file depends on your project layout. With the default Symfony AssetMapper recipe it is assets/bootstrap.js or assets/app.js. Anywhere your Application.start() runs is fine.

Deprecated: install via Composer (web-auth/webauthn-stimulus)

This command installs the PHP wrapper, which used to register the Stimulus controllers via Symfony Flex and configure AssetMapper to import them from a vendored copy. As of v5.3.0 the same JavaScript ships on npm and the PHP wrapper no longer brings any added value — it is scheduled for removal in 6.0.0.

What's Included

The package provides Stimulus controllers that handle:

  • Registration flows — calls navigator.credentials.create() for you

  • Authentication flows — calls navigator.credentials.get() for you

  • Base64 encoding/decoding — automatically handles data conversion

  • Error handling — gracefully handles common WebAuthn errors

  • Browser autofill — supports conditional UI for passkey selection

  • Conditional create (v5.3.0+) — enhanced conditional UI support for both registration and authentication

  • PRF extension — built-in support for the Pseudo-Random Function extension

Three controllers ship in the package:

  • WebauthnController — combined controller (legacy, still supported)

  • AuthenticationController — dedicated authentication controller

  • RegistrationController — dedicated registration controller

The dedicated controllers offer better separation of concerns, enhanced conditional UI support, and improved error handling. The combined controller remains available for backward compatibility.

Basic Usage

Once the controllers are registered, you can use them in your Twig templates with the standard Symfony UX helpers:

  1. stimulus_controller() — attaches a controller to your form

  2. stimulus_action() — triggers WebAuthn operations on button clicks

  3. stimulus_target() — marks an input as a controller target

The first argument is the package-prefixed name — it will resolve to the ---separated identifier you registered in step 2.

Registration Form Example

Authentication Form Example

Controller Options

The dedicated controllers accept the following options. See the User Authentication and User Registration pages for the full list of values, targets, actions and events.

Registration Options

Option
Type
Default
Description

optionsUrl

string

/registration/options

URL to fetch creation options

resultUrl

string

/registration/verify

URL to submit the attestation response

submitViaForm

boolean

false

Submit via form instead of fetch

successRedirectUri

string

URL to redirect after successful registration

autoRegister

boolean

false

Auto-start registration on page load

Authentication Options

Option
Type
Default
Description

optionsUrl

string

/authentication/options

URL to fetch assertion options

resultUrl

string

/authentication/verify

URL to submit the assertion response

submitViaForm

boolean

false

Submit via form instead of fetch

successRedirectUri

string

URL to redirect after successful auth

conditionalUi

boolean

false

Enable conditional UI (autofill)

Troubleshooting

Could not find package "web-auth/webauthn-stimulus" referred to from controllers.json

You added @web-auth/webauthn-stimulus to assets/controllers.json. Remove that entry. The npm package is not a Symfony UX PHP package — controllers.json is wrong here. Register the controllers from your JS bootstrap file instead, as shown in step 2 above.

Controller not found

If you see "application Error: Controller 'web-auth--webauthn-stimulus--authentication' is not registered" (or similar):

  1. Verify the identifier in app.register('web-auth--webauthn-stimulus--authentication', ...) matches the rendered data-controller attribute. Remember stimulus_controller('@web-auth/webauthn-stimulus/authentication') produces data-controller="web-auth--webauthn-stimulus--authentication".

  2. Make sure your bootstrap file is included by your importmap ({{ importmap('app') }} in your base template).

  3. Clear Symfony cache: php bin/console cache:clear.

JavaScript errors

If you see console errors:

  1. Ensure you're using HTTPS (required for WebAuthn).

  2. Check browser console for specific error messages.

  3. Verify WebAuthn routes are properly configured in config/routes/webauthn.yaml.

  4. Ensure the controller is loaded by checking the browser's network tab.

HTTPS Requirement

WebAuthn requires HTTPS to function. For development, use the Symfony CLI for automatic HTTPS:

For production, ensure HTTPS is properly configured on your web server.

Next Steps

Now that the Stimulus Controller is installed, proceed to:

  1. User Registration — create registration forms

  2. User Authentication — implement login flows

  3. Additional Authenticators — allow users to register backup devices

See Also

Last updated

Was this helpful?