Skip to content
Deployment
Skill

/netlify-identity

Add user authentication to a Netlify site with @netlify/identity — signup/login/logout, Google/GitHub/GitLab/Bitbucket OAuth, server-side getUser() checks, role-based access control, and Identity event functions. Use it when a task involves adding a login or signup form, gating

From plugin
netlify-skills
4915 skills1 MCP

Claude Code

$ npx -y skills add netlify/context-and-tools --skill netlify-identity --agent claude-code

SKILL.md

netlify-identity.SKILL.md
name: netlify-identity
description: Add user authentication to a Netlify site with @netlify/identity, covering signup/login/logout, Google/GitHub/GitLab/Bitbucket OAuth, server-side getUser() checks, role-based access control, and Identity event functions. Use it when a task involves adding a login or signup form, gating content to members or roles, "auth middleware" or verifying users in Netlify Functions or Edge Functions, handling OAuth or email-confirmation callbacks, accepting user invites, assigning roles at signup, or customizing Identity emails. For locking a whole site to your company or employees-only access, use netlify-access-control instead.

Netlify Identity

Use `@netlify/identity` (npm). For new projects it replaces the legacy `netlify-identity-widget` and `gotrue-js`. Do not reach for those.

npm install @netlify/identity

Framework examples (Next.js/Astro/Remix/SvelteKit) and the full API reference are in the [`@netlify/identity` README on npm](https://www.npmjs.com/package/@netlify/identity).

> **Identity does not run under `netlify dev`.** Test all auth flows on a deploy. Deploy Previews work. Local dev will not complete signup/login/OAuth.

> **Identity config is dashboard-only. There is no public API.** Never curl `api.netlify.com` to flip or read Identity settings, never read tokens from local Netlify config, and never probe undocumented endpoints. Enable and configure Identity at `https://app.netlify.com/projects/{site_name}/identity`.

> **Never build a from-scratch OAuth flow alongside Identity.** No provider app registration in code, no `client_id`/`secret` in source, and no custom callback token exchange. Use `oauthLogin()` + `handleAuthCallback()`. Raw OAuth beside Identity is the most common source of rework.

Client auth (browser)

import { signup, login, logout, getUser, oauthLogin, handleAuthCallback } from '@netlify/identity'

// Register — confirmation email sent by default (unless autoconfirm is on)
const user = await signup('jane@example.com', 'securepassword', { full_name: 'Jane Doe' })

// Log in / out
await login('jane@example.com', 'securepassword')
await logout()

// Current user or null
const current = await getUser()
if (current) console.log(`Logged in as ${current.email}`)

// External provider — redirects the browser; provider is one of
// 'google' | 'github' | 'gitlab' | 'bitbucket'
oauthLogin('github')

> **`handleAuthCallback()` is mandatory on your landing page.** Without it, OAuth redirects, email-confirmation links, password-recovery links, and invite links never complete. Call it on page load.

> **Invites are NOT logged in by `handleAuthCallback()`.** For an invite it returns `type === 'invite'` with the token in `result.token` and `result.user === null`. The account does not exist yet. You must collect a password and call `acceptInvite(result.token, password)`. If you skip this step, invited users never get an account.

import { handleAuthCallback, acceptInvite } from '@netlify/identity'

const result = await handleAuthCallback() // falsy if no token in URL hash
if (result?.type === 'invite' && result.token) {
  // Invited user has no account yet. Ask them to choose a password first.
  const password = (document.getElementById('password') as HTMLInputElement).value
  const user = await acceptInvite(result.token, password)
  console.log('Account created:', user.email)
} else if (result) {
  // OAuth, email confirmation, recovery, or email change
  console.log(result.type, result.user?.email)
}

For recovery tokens you can call `recoverPassword()` directly instead. Refresh a session with `refreshSession()`.

Don't hard-code which providers exist. Call `getSettings()` at startup and render the signup form and OAuth buttons from what it returns.

Server-side auth (Netlify Functions & Edge Functions)

Server-side `getUser()`/`login()`/`admin.*` require modern **v2 functions** (`export default`). The v1 `export { handler }` form is not supported.

`getUser()` works in both runtimes. **`admin.*` runs ONLY in Netlify Functions. It does not run in the browser or in Edge Functions.**

// netlify/functions/me.ts — verify user
import { getUser } from '@netlify/identity'
import type { Context } from '@netlify/functions'

export default async (req: Request, context: Context) => {
  const user = await getUser()
  if (!user) return new Response('Unauthorized', { status: 401 })
  return Response.json({ id: user.id, email: user.email })
}

The Edge Function form is identical but imports `Context` from `@netlify/edge-functions`.

Role checks

// netlify/functions/admin-users.ts
import { getUser, admin } from '@netlify/identity'
import type { Context } from '@netlify/functions'

export default async (req: Request, context: Context) => {
  const user = await getUser()
  if (!user) return new Response('Unauthorized', { status: 401 })
  if (!user.roles.includes('admin')) return new Response('Forbidden', { status: 403 })
  const users = await admin.listUsers()
  return Response.json({ users })
}

CSRF: required for server-side auth endpoints

> Any endpoint that runs `login()`, `signup()`, or `logout()` server-side **must** call `verifyRequestOrigin(req)` at the top of the handler. It throws a 403 on origin mismatch.

// netlify/functions/login.ts
import { login, verifyRequestOrigin } from '@netlify/identity'
import type { Context } from '@netlify/functions'

export default async (req: Request, context: Context) => {
  verifyRequestOrigin(req)
  const { email, password } = await req.json()
  await login(email, password)
  return new Response(null, { status: 302, headers: { Location: '/dashboard' } })
}

Identity event functions

The platform calls your handler when an Identity event occurs. Export a default object with a method per event. File: `netlify/functions/identity.mts`.

> Typed handlers (`UserSignupEvent`, `event.deny()`) require `@netlify/functions` ≥ 5.2.0.

Read more
@netlify
Ships withnetlify-skills

Public Netlify skills for AI coding agents. Each skill is a focused, factual reference for a Netlify platform primitive — designed to help agents build correctly on Netlify without needing to search docs.

4915 skills1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
49
Star history of netlify/context-and-tools on GitHub, a chart by star-history.com

Other skills on netlify-skills.

netlify-blobs

netlify-blobs

Store and retrieve unstructured objects, files, and cache-like state on Netlify with the @netlify/blobs module. Use when…

netlify-caching

netlify-caching

Cache dynamic and static responses on Netlify's CDN from Functions, Edge Functions, and proxies. Use when you add caching or…

netlify-config

netlify-config

Configure Netlify builds and routing via netlify.toml, _redirects, and _headers. Use when setting a build command or publish…

More skills from other plugins.

configuring-horizon

configuring-horizon

Use this skill whenever the user mentions Horizon by name in a Laravel context. Covers the full Horizon lifecycle: installing…

coolify10d66k
@coollabsio@coollabsioInstall Skill
vercel-cli

vercel-cli

Guides deployment, configuration, and troubleshooting with the Vercel CLI. Use when operating Vercel projects or resources…

vercel12d16k
@vercel@vercelInstall Skill
skypilot

skypilot

Use when launching cloud VMs, Kubernetes pods, or Slurm jobs for GPU/TPU/CPU workloads, training or fine-tuning models on cloud…

@skypilot-org@skypilot-orgInstall Skill
pinme

pinme

Use this skill when the user mentions "pinme", or needs to upload files, store to IPFS, create/publish/deploy websites or…

pinme2mo3.8k
@glitternetwork@glitternetworkInstall Skill

Questions about netlify-identity.

Which coding agents can use netlify-identity?
netlify-identity installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.