# Custom Protocols Custom protocols handle URL schemes such as `app://` without starting a local HTTP server. Register each scheme before creating a webview. ```js import { readFile } from 'node:fs/promises'; import { extname, join } from 'node:path'; import { Application } from '@webviewjs/webview'; const MIME = { '.html': 'text/html; charset=utf-8', '.js': 'application/javascript; charset=utf-8', '.css': 'text/css', }; const app = new Application(); const win = app.createBrowserWindow(); win.registerProtocol('app', async (request) => { const url = new URL(request.url); const path = join(process.cwd(), 'dist', url.pathname); try { return new Response(await readFile(path), { headers: { 'Content-Type': MIME[extname(path)] ?? 'application/octet-stream' }, }); } catch { return new Response(`Not found: ${url.pathname}`, { status: 404, headers: { 'Content-Type': 'text/plain; charset=utf-8' }, }); } }); win.createWebview({ url: 'app://localhost/index.html' }); app.run(); ``` The handler receives the standard global Fetch API `Request`. It may return a `Response`, a Promise of a `Response`, or the legacy plain object shown below. This makes Fetch-compatible routers such as Hono usable directly. Rejected handlers and thrown errors become a `500 text/plain` response. ## Hono Forward the request directly to a Hono application. Hono returns a standard Fetch API `Response`, so no adapter or HTTP server is required: ```js import { Hono } from 'hono'; const router = new Hono(); router.get('/*', (context) => { return context.html(`