Adding modules
What you'll have afterwards:
- A new feature in your app, such as forms, payments or events, with its pages in the admin area.
- Its tables in your database, through a committed migration.
Each module adds one feature to your host app. It installs the modules it depends on, so you usually add only the one you want. This page helps you pick a module and walks through adding one.
Prerequisites
A project created in Installation.
Which module do I need?
| I want to... | Use |
|---|---|
| Let people sign in with a password, magic link, passkey or OAuth, and protect routes | Auth |
| Store users and let staff manage them | Users |
| Decide who may do what, by role | Authorization |
| Give users profile, security, documents and API token pages | Account |
| Keep typed per-user settings | Preferences |
| Be an OAuth 2.0 / OpenID Connect issuer for other apps | OAuth Server |
| Accept frigear.nu sign-ins in another service (a resource server) | OAuth Resource |
| Sign users in from a single-page app (SPA) or a Capacitor app, with PKCE (Proof Key for Code Exchange) | Auth in client mode |
| Ship a Nuxt app as an iOS or Android app | Mobile |
| Expose scoped tools to AI agents over the Model Context Protocol (MCP) | MCP |
| Take payments or sell subscriptions with Stripe | Stripe, Payments, Subscriptions |
| Run events with tickets and check-in | Events |
| Build forms stored in the database | Forms |
| Show a cookie consent banner | Cookie Consent |
| Build navigation, dashboard widgets or an admin area | Menu, Widget, Admin |
| Share interface components and dialogs | UI |
| Send email, SMS or other notifications | Notify |
| Write a new module | Writing a module, Module Kit |
Add a module
Every module follows the same steps. This example adds Forms: forms stored in the database, with admin pages to edit them and read submissions.
modules) in one go:
pnpx @frigear-nu/cli add forms. The options, the encryption key, the role grants and the migration are still yours.Install the module
Install it in the app, from the project root:
pnpm --filter ./apps/web add @frigear-nu/forms
Add it to nuxt.config.ts
Add it to modules in apps/web/nuxt.config.ts and set its options. The module page lists them. It also lists what the
module needs from NuxtHub: Forms uses key-value storage (KV) for rate limiting and blob storage for uploads.
export default defineNuxtConfig({
modules: [
// ...
'@frigear-nu/forms',
],
hub: {
kv: true,
blob: true,
db: { dialect: 'sqlite', driver: 'libsql', connection: { url: 'file:./.data/db/sqlite.db' } },
},
forms: {
settings: {
pages: { form: true, admin: true, adminForm: true, adminSubmissions: true, adminSubmission: true },
},
},
})
Set its encryption key
Forms encrypts per-form secrets in the database. The starter has no key it can fall back to, so add one to
apps/web/.env (and to your production environment), at least 32 characters, e.g. openssl rand -base64 32:
NUXT_FORMS_ENCRYPTION_KEY=
Keep it stable: a new key makes the stored secrets unreadable.
Give its permissions to a role
Your app decides who is staff, as it does for user management. Forms registers forms:manage, forms:credentials and
forms:pii, and gives them to the admin role by default (grantTo). To let another role manage forms, grant them in
authorization.roles:
export default defineNuxtConfig({
authorization: {
roles: {
coordinator: { label: 'Coordinator', grant: ['forms:manage', 'forms:credentials'], inherit: ['user'] },
},
},
})
forms:pii (submission answers through MCP tools) is sensitive: a wildcard such as forms:* never covers it, so grant
it by name. Without Authorization nobody holds a staff permission, unless your
authorization:before hook allows it.
Generate the migration
The module adds tables, so generate a migration and commit it:
pnpm db:generate
Run it after every module you add or upgrade. It prints No schema changes, nothing to migrate when the database is
already up to date.
Restart the app
Restart pnpm dev. The new migration is applied on start.
/admin, open to users with the admin role.What a module page tells you
Each module page lists what the module needs under Requires, Options and Hooks:
- the other modules it installs or works with,
- the NuxtHub features it uses,
- the permissions it registers, and which roles get them by default,
- the environment variables it reads, such as Stripe keys.
A module declares the modules it depends on, and Nuxt installs them with it. So you list only the ones you want.
Next steps
- Database – understand the migration you just generated.
- Build a form – publish your first form now that Forms is installed.
- Writing a module – build a module of your own.