Astro integration and headless runtime client for fa-auth-m8.
Part of the M8 auth stack: mano8/astro-auth-m8 is the Astro plugin layer for the mano8/fa-auth-m8 backend service, and it is ready to compose into mano8/fa-ui-m8.
npm install @mano8/astro-auth-m8Use it with a fa-auth-m8 backend that satisfies the fa-auth-m8@1.0 contract.
This package targets the fa-auth-m8@1.0 API contract and was tested against fa-auth-m8 service version 1.1.0. Supported backend service versions are >=1.0.0 <2.0.0.
Compatibility helpers are exported from @mano8/astro-auth-m8/compatibility. fa-auth-m8 (>= 1.0.0) exposes a public GET {API_PREFIX}/meta route returning a ServiceMeta payload - pass it straight to the assert:
import { assertFaAuthM8Compatibility } from "@mano8/astro-auth-m8/compatibility";
const meta = await fetch(`${base}/user/meta`).then((r) => r.json());
// meta = { service, version, api_version, contract: { name, version, range } }
assertFaAuthM8Compatibility(meta); // reads nested contract.version + versionThe helper also accepts flat fields (auth_contract_version / contract_version / service_version) for backends that surface metadata elsewhere.
headless: exports typed schemas, API wrappers, token handling, React provider/hooks, and route helpers without injecting pages.starter: injects small default login, logout, callback, and account routes withinjectRoute().scaffold: copies editable Astro/React/CSS files into a consumer app withastro-auth-m8 scaffold --views --target src/auth.
import { defineConfig } from "astro/config";
import react from "@astrojs/react";
import faAuth from "@mano8/astro-auth-m8";
export default defineConfig({
integrations: [
react(),
faAuth({
apiBase: "/user",
mode: "starter",
routes: { base: "/[locale]" }
})
]
});The runtime keeps access tokens in memory only, sends refresh requests with credentials: "include", and models public backend responses without secret session fields.
For shadcn/Tailwind apps, this package ships a shadcn registry of ready-to-run styled views. The headless logic stays a live dependency (@mano8/astro-auth-m8/react + /hooks); only the skin is copied into the consumer, so views adopt the app's own tokens and are fully editable. The registry items are pre-built into the package at registry/r/*.json (regenerate with npm run build:registry; the output is byte-for-byte identical to shadcn build).
Shared table and state primitives live in @mano8/astro-ui-m8. This package depends on it normally because auth registry items reference astro-ui-m8 generated registry JSON from node_modules.
Install @mano8/astro-auth-m8 from npm first, then consume the registry as a local file out of node_modules (no external host or token). Because shadcn resolves namespaced registries (@name/item) over HTTP, local consumption uses the direct .json path form of shadcn add. Optionally declare the namespace in components.json for documentation or future HTTP hosting:
| Item | shadcn add (run from the consumer project root) |
registryDependencies | npm dependencies | Needs @mano8/astro-auth-m8? |
|---|---|---|---|---|
activity-bar-chart |
npx shadcn add ./node_modules/@mano8/astro-auth-m8/registry/r/activity-bar-chart.json |
chart |
recharts |
no |
dashboard-overview |
npx shadcn add ./node_modules/@mano8/astro-auth-m8/registry/r/dashboard-overview.json |
card, skeleton, activity-bar-chart |
none | yes (useDashboard) |
account-dashboard |
npx shadcn add ./node_modules/@mano8/astro-auth-m8/registry/r/account-dashboard.json |
button, skeleton, tabs, dashboard-overview |
none | yes (AuthProvider, useAuth) |
profile-panel |
npx shadcn add ./node_modules/@mano8/astro-auth-m8/registry/r/profile-panel.json |
card, button, input, label |
none | yes (useAuth, useProfile) |
sessions-panel |
npx shadcn add ./node_modules/@mano8/astro-auth-m8/registry/r/sessions-panel.json |
card, button |
lucide-react |
yes (useAuth, useSessions, useDashboard) |
account-crud |
npx shadcn add ./node_modules/@mano8/astro-auth-m8/registry/r/account-crud.json |
button, dialog, alert-dialog, astro-ui-m8 data-table and toast |
lucide-react |
no |
api-keys-panel |
npx shadcn add ./node_modules/@mano8/astro-auth-m8/registry/r/api-keys-panel.json |
card, button, input, label, badge, dialog, account-crud, astro-ui-m8 data-table |
lucide-react, @tanstack/react-table |
yes (useApiKeys) |
admin-users-panel |
npx shadcn add ./node_modules/@mano8/astro-auth-m8/registry/r/admin-users-panel.json |
card, button, input, label, badge, dialog, account-crud, astro-ui-m8 data-table |
lucide-react, @tanstack/react-table |
yes (RequireRole, useUsers) |
dashboard-overview is the landing view; profile-panel, sessions-panel, api-keys-panel, and admin-users-panel are the secondary account tabs (drop them into account-dashboard's extraTabs, or into your own shell). Each reads its headless logic straight from the package hooks - no local adapter layer - and takes its strings via labels. api-keys-panel and admin-users-panel use the canonical astro-ui-m8 data-table with client-side search, sorting, pagination, column visibility, and row selection. Their shared account-crud dependency is installed automatically; it supplies the popup form, destructive-action confirmation, fixed row actions, and bottom-right toast host. admin-users-panel self-gates with RequireRole superuser.
Files land under src/components/fa-auth/ (the items' target), import shadcn primitives via @/components/ui/*, and pull headless logic from the installed package. The plugin package is intentionally not listed in registry item dependencies; install the published @mano8/astro-auth-m8 package from npm yourself so shadcn only copies the skin files.
When a copied auth skin references @mano8/astro-ui-m8 registry items, shadcn will also copy those files into src/components/m8-ui/ from ./node_modules/@mano8/astro-ui-m8/registry/r/*.json.
- shadcn configured with
style: radix-nova,baseColor: neutral,cssVariables: true, lucide icons, and Tailwind v4 tokens insrc/styles/global.css. - The published
@mano8/astro-auth-m8npm package installed and anAuthProviderin the tree (the dashboard hooks read the package's configured client). - All view labels are props with English defaults - pass your own i18n strings to localize.