diff --git a/docs/content/docs/(documentation)/integration/(frameworks)/meta.json b/docs/content/docs/(documentation)/integration/(frameworks)/meta.json index 39b253cd..34e2a6c0 100644 --- a/docs/content/docs/(documentation)/integration/(frameworks)/meta.json +++ b/docs/content/docs/(documentation)/integration/(frameworks)/meta.json @@ -1,11 +1,3 @@ { - "pages": [ - "nextjs", - "react-router", - "astro", - "sveltekit", - "tanstack-start", - "vite", - "nuxt" - ] + "pages": ["nextjs", "react-router", "astro", "sveltekit", "tanstack-start", "vite", "nuxt", "web"] } diff --git a/docs/content/docs/(documentation)/integration/(frameworks)/web.mdx b/docs/content/docs/(documentation)/integration/(frameworks)/web.mdx new file mode 100644 index 00000000..05d1be13 --- /dev/null +++ b/docs/content/docs/(documentation)/integration/(frameworks)/web.mdx @@ -0,0 +1,210 @@ +--- +title: "Web Adapter" +description: "Bring bknd to any web framework or runtime" +tags: ["documentation"] +--- + +## What is the Web Adapter? + +The web adapter (`bknd/adapter/web`) is your universal connector. Use it to integrate bknd into **any** web framework or runtime — even ones without a dedicated adapter. + +**Use the web adapter when:** +- Your framework doesn't have a dedicated bknd adapter +- You want full control over your server setup +- You're building a custom server or edge function + +**Use a platform-specific adapter when:** +- You're using a supported framework (Next.js, SvelteKit, Nuxt, Astro, etc.) +- You prefer opinionated, zero-config setup + +## Installation + + + +```bash tab="npm" +npm install bknd +``` + +```bash tab="pnpm" +pnpm install bknd +``` + +```bash tab="yarn" +yarn add bknd +``` + +```bash tab="bun" +bun add bknd +``` + + + +## Basic Setup + +Create a config file and initialize the adapter: + +```typescript title="bknd.config.ts" +import type { WebBkndConfig } from "bknd/adapter/web"; + +export default { + connection: { + url: "file:data.db", + }, +} satisfies WebBkndConfig; +``` + +```typescript title="src/bknd.ts" +import { createBknd } from "bknd/adapter/web"; +import config from "../bknd.config"; + +export const bknd = createBknd(config, process.env); +``` + +`createBknd` returns three methods: + +| Method | Returns | Description | +|--------|---------|-------------| +| `getApp()` | `Promise` | The built bknd app instance (cached) | +| `getApi({ headers, verify })` | `Promise` | Convenience wrapper around `app.getApi()` | +| `serve()` | `(req: Request) => Promise` | A fetch handler for your server | + +## Choosing an Admin UI Path + +The web adapter supports two approaches to serving the admin UI: + +| Path | Best For | How | +|------|----------|-----| +| **Client-side** (default) | React frameworks: Next.js, Astro, React Router, Tanstack Start | Import and render `` in your own React route | +| **Server-side** | Non-React frameworks: SvelteKit, Nuxt, Bun, Node, Deno | The server serves the admin HTML and assets | + +## Path 1: Client-Side Admin (Default) + +For React-capable frameworks, render the admin UI directly in a route: + +```tsx title="app/admin/[[...admin]]/page.tsx" +import { Admin } from "bknd/ui"; +import "bknd/dist/styles.css"; +import { bknd } from "@/bknd"; + +export default async function AdminPage() { + const api = await bknd.getApi({ verify: true }); + + return ( + + ); +} +``` + +No server-side admin configuration needed. The admin UI runs entirely in the browser. + +## Path 2: Server-Side Admin + +For non-React frameworks or standalone servers, enable the admin controller: + +```typescript title="src/bknd.ts" +import { createBknd } from "bknd/adapter/web"; +import config from "../bknd.config"; + +export const bknd = createBknd({ + ...config, + adminOptions: { + adminBasepath: "/admin", + }, +}, process.env); +``` + +You'll also need to serve the admin's static assets (JS, CSS). Choose one of three strategies: + +### Strategy 1: serveStatic Middleware + +**Best for:** Bun, Node, standalone servers with filesystem access + +Use Hono's platform-specific `serveStatic` to serve assets from `node_modules/bknd/dist/static/`: + +```typescript title="src/bknd.ts" +import { createBknd } from "bknd/adapter/web"; +import { serveStatic } from "hono/bun"; // or "@hono/node-server/serve-static" +import config from "../bknd.config"; + +export const bknd = createBknd({ + ...config, + adminOptions: { adminBasepath: "/admin" }, + serveStatic: serveStatic({ root: "./node_modules/bknd/dist/static" }), +}, process.env); +``` + +### Strategy 2: copy-assets Postinstall + +**Best for:** SvelteKit, Nuxt, any framework with a static directory + +Copy assets at install time and let your framework serve them: + +```json title="package.json" +{ + "scripts": { + "postinstall": "bknd copy-assets --out static" + } +} +``` + +Per-framework output paths: + +| Framework | `--out` flag | +|-----------|-------------| +| SvelteKit | `--out static` | +| Nuxt | `--out public` | +| Next.js | `--out public` | +| Astro | `--out public` | + +### Strategy 3: serveStaticViaImport + +**Best for:** Edge/serverless runtimes (Deno Deploy, Cloudflare Workers) + +For environments without filesystem access: + +```typescript title="src/bknd.ts" +import { createBknd } from "bknd/adapter/web"; +import { serveStaticViaImport } from "bknd/adapter"; +import config from "../bknd.config"; + +export const bknd = createBknd({ + ...config, + adminOptions: { adminBasepath: "/admin" }, + serveStatic: serveStaticViaImport(), +}, process.env); +``` + +## Serving Requests + +Use `bknd.serve()` as a fetch handler in your server: + +```typescript title="server.ts" +import { bknd } from "./bknd"; + +// Bun +Bun.serve({ fetch: bknd.serve(), port: 3000 }); + +// Node (with @hono/node-server) +import { serve } from "@hono/node-server"; +serve({ fetch: bknd.serve(), port: 3000 }); +``` + +Or use `bknd.getApp()` to integrate with an existing Hono or other router setup. + +## Reference: WebBkndConfig + +```typescript +type WebBkndConfig = FrameworkBkndConfig & { + /** Serve the admin UI from the server. Omit for client-side admin. */ + adminOptions?: AdminControllerOptions; + + /** Hono middleware for serving bknd's bundled JS/CSS assets. */ + serveStatic?: MiddlewareHandler | [string, MiddlewareHandler]; + + /** Override path to bknd's dist folder (default: ./node_modules/bknd/dist) */ + distPath?: string; +}; +``` diff --git a/docs/content/docs/(documentation)/integration/introduction.mdx b/docs/content/docs/(documentation)/integration/introduction.mdx index a04cb12c..c43a9d39 100644 --- a/docs/content/docs/(documentation)/integration/introduction.mdx +++ b/docs/content/docs/(documentation)/integration/introduction.mdx @@ -45,6 +45,8 @@ bknd seamlessly integrates with popular frameworks, allowing you to use what you href="/integration/nuxt" /> + } title="Web Adapter" href="/integration/web" /> + Create a new issue to request a guide for your framework. @@ -108,6 +110,8 @@ If you prefer to use a runtime instead of a framework, you can choose from the f href="/integration/docker" /> +} title="Web Adapter" href="/integration/web" /> + Create a new issue to request a guide for your runtime. diff --git a/docs/content/docs/(documentation)/start.mdx b/docs/content/docs/(documentation)/start.mdx index d0644ae2..d3bcfd28 100644 --- a/docs/content/docs/(documentation)/start.mdx +++ b/docs/content/docs/(documentation)/start.mdx @@ -185,6 +185,8 @@ Pick your framework or runtime to get started. href="/integration/docker" /> +} title="Web Adapter" href="/integration/web" /> + Create a new issue to request a guide for your runtime or framework.