### Clone and Run Transclude Examples Source: https://transclude.dev/docs/examples Commands to clone the repository and start specific example projects on their respective ports. ```bash git clone https://github.com/transclude-dev/transclude.git cd transclude && npm install npm run showcase # http://localhost:1961 npm run todomvc # http://localhost:1962 npm run blog # http://localhost:1963 npm run search # http://localhost:1964 npm run htmx # http://localhost:1965 npm run includes # http://localhost:1966 npm run auth # http://localhost:1967 npm run live # http://localhost:1968 npm run elements # http://localhost:1969 npm run markdown # http://localhost:1970 ``` -------------------------------- ### Install Transclude core Source: https://transclude.dev/docs/getting-started Manual installation command for adding Transclude to an existing project. ```bash npm install @transclude/core ``` -------------------------------- ### Clone and run the project Source: https://transclude.dev/docs/contributing Commands to clone the repository, install dependencies, and execute the test suite. ```bash git clone https://github.com/transclude-dev/transclude.git cd transclude npm install npm test ``` -------------------------------- ### Start Transclude Application Across Runtimes Source: https://transclude.dev/docs/runtimes Commands to initiate the application server in various runtime environments. ```bash npm start # Node bun node_modules/@transclude/core/bin/serve.bun.js # Bun deno run -A node_modules/@transclude/core/bin/serve.deno.js # Deno wrangler dev # Cloudflare ``` -------------------------------- ### Usage examples for svg-icon Source: https://transclude.dev/docs/icons Demonstrates various ways to use the svg-icon element in markup. ```html

Saved

``` -------------------------------- ### Define a full transclude configuration Source: https://transclude.dev/docs/config Example of a complete configuration object defining directory paths, server settings, and build options. ```javascript export default { appDir: 'app', routesDir: 'routes', elementsDir: 'elements', iconsDir: 'icons', publicDir: 'public', stylesheet: 'app/styles/global.css', strict: false, fragmentParam: 'fragment', lang: 'en', watchElements: false, fragmentHeader: null, csrf: true, trailingSlash: 'never', cookieSecret: globalThis.process?.env?.COOKIE_SECRET ?? null, port: 1960, proxy: false, outDir: 'dist', typesFile: 'app/transclude-env.d.ts', }; ``` -------------------------------- ### Route path mapping Source: https://transclude.dev/docs/endpoints Examples of how file paths in the routes directory map to URL patterns. ```text routes/api/people.js /api/people routes/api/people/[id].js /api/people/:id routes/api/[...rest].js /api/* routes/api/_shared.js not a route ``` -------------------------------- ### Create POST Response with Cookies Source: https://transclude.dev/docs/endpoints Example of handling form data, setting a cookie, and returning a custom response with status and headers. ```javascript export const POST = async ({ cookies, request }) => { const form = await request.formData(); cookies.set('seen', '1', { maxAge: 604800 }); return new Response('made', { status: 201, headers: { location: '/api/people/' + form.get('id') }, }); }; ``` -------------------------------- ### Define a route page Source: https://transclude.dev/docs/getting-started Example of a route file using a server-side script block to provide data to the template. ```html ${title}

${title}

``` -------------------------------- ### Fragment response example Source: https://transclude.dev/docs/fragments The server returns only the requested fragment element when the fragment query parameter matches the element's id. ```html ``` -------------------------------- ### Anchor and Heading Structure Source: https://transclude.dev/docs/includes Uses an empty anchor tag as a bookmark to define the start of a section. ```html

Installing

Run the thing.

``` -------------------------------- ### HTTP request and response mapping Source: https://transclude.dev/docs/endpoints Example of how HTTP methods map to status codes and responses for the people API. ```text GET /api/people -> 200 [{ "name": "Ada" }] POST /api/people -> 201 { "name": "Grace" } PUT /api/people -> 405 Allow: GET, POST ``` -------------------------------- ### Create a JSON API endpoint Source: https://transclude.dev/docs/recipes Defines GET and POST handlers for a JSON API route using standard Response objects. ```javascript // app/routes/api/people.js -> /api/people import { people } from '../../data/people.js'; export const GET = () => Response.json(people); export const POST = async ({ request }) => { const body = await request.json(); people.push(body); return Response.json(body, { status: 201 }); }; ``` -------------------------------- ### Unsafe Script and Style Injection Source: https://transclude.dev/docs/security Examples of insecure template expressions within script and style tags that can lead to syntax errors or injection vulnerabilities. ```html ``` -------------------------------- ### GET /api/people Source: https://transclude.dev/docs/endpoints Retrieves the list of all people. ```APIDOC ## GET /api/people ### Description Retrieves a list of all people from the data source. ### Method GET ### Endpoint /api/people ### Response #### Success Response (200) - **people** (array) - A list of person objects. ``` -------------------------------- ### GET /api/people/:id Source: https://transclude.dev/docs/endpoints Retrieves a specific person by their ID. ```APIDOC ## GET /api/people/:id ### Description Retrieves details for a specific person identified by the provided ID. ### Method GET ### Endpoint /api/people/:id ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the person. ### Response #### Success Response (200) - **person** (object) - The requested person object. #### Error Response (404) - **error** (string) - Returned when the person is not found. ``` -------------------------------- ### Build the project Source: https://transclude.dev/docs/colophon Execute the build process to generate static files for the site. ```bash npm run build ``` -------------------------------- ### GET /_transclude/proxy Source: https://transclude.dev/docs/includes Fetches a document fragment or an outline from a specified URL. ```APIDOC ## GET /_transclude/proxy ### Description Retrieves a fragment of an allowed document or the document's outline if no ID is provided. The response is sanitized and links are rewritten. ### Method GET ### Endpoint /_transclude/proxy ### Parameters #### Query Parameters - **url** (string) - Required - The URL of the document to fetch. - **id** (string) - Optional - The ID of the specific fragment to retrieve. If omitted, returns the document outline. ### Response #### Success Response (200) - **fragments** (array) - List of fragments (if no ID provided) - **url** (string) - The source URL - **HTML content** (string) - The requested fragment (if ID provided) ``` -------------------------------- ### Build and Serve Production Site Source: https://transclude.dev/docs/production Commands to generate the production build and serve the resulting files. ```bash npm run build npm start # serves dist/ on 1960 ``` -------------------------------- ### Common Compilation Errors Source: https://transclude.dev/docs/routing Examples of invalid directive usage that result in compile-time errors. ```html
  • …
  • A

    B

  • …
  • Nobody here.

    ${person.name} ``` -------------------------------- ### Initialize a new Transclude project Source: https://transclude.dev/docs/getting-started Commands to scaffold a new project with default or blank templates. ```bash npm create @transclude my-app cd my-app npm install npm run dev ``` ```bash npm create @transclude my-app -- --template blank ``` -------------------------------- ### Transclusion Compile Errors Source: https://transclude.dev/docs/includes Examples of invalid transclusion patterns that result in compile-time errors. ```html
    ``` -------------------------------- ### Define a basic layout Source: https://transclude.dev/docs/layouts A _layout.html file wraps routes in its directory and below, using a to render nested content. ```html
    ``` -------------------------------- ### Create a dynamic route Source: https://transclude.dev/docs/recipes Use bracketed file names to define URL parameters, which are accessible via the context params object. ```html

    ${person.name}

    ``` -------------------------------- ### Mutation Redirect Pattern Source: https://transclude.dev/docs/forms Redirecting after a successful mutation to ensure the browser lands on a GET request. ```javascript export const POST = async ({ request, url, fragment }) => { const result = await save(request); if (result.error) return result; if (fragment !== null) return result; return Response.redirect(new URL(url), 303); }; ``` -------------------------------- ### Enable Content-Security-Policy Source: https://transclude.dev/docs/security Enable the Content-Security-Policy by setting the csp key to true in the configuration file. ```javascript // transclude.config.js export default { csp: true, }; ``` -------------------------------- ### Diagnostic Error Reporting Source: https://transclude.dev/docs/markdown Example of a diagnostic message pointing to a line number in the converted HTML output. ```text app/routes/notes.md (converted HTML, line 21) error TS2551 Property 'cuont' does not exist on type '__Shape<{ title: string; count: number; }>'. ``` -------------------------------- ### Configure basic sitemap Source: https://transclude.dev/docs/feeds Define the hostname for sitemap generation in the default export. ```javascript export default { sitemap: { hostname: 'https://acme.com' }, }; ``` -------------------------------- ### Configure icon directory Source: https://transclude.dev/docs/icons Set the icons directory path in the project configuration. ```javascript export default { iconsDir: 'icons', }; ``` -------------------------------- ### Configure vite.config.js Source: https://transclude.dev/docs/getting-started Optional configuration file for adding custom Vite plugins. ```javascript // vite.config.js, only if you want one import { defineConfig } from 'vite'; import tailwind from '@tailwindcss/vite'; export default defineConfig({ plugins: [tailwind()], }); ``` -------------------------------- ### Configure worker.js for Transclude Source: https://transclude.dev/docs/runtimes Standard worker entry point configuration using workerFrom to integrate application assets, manifest, and configuration. ```javascript // worker.js import { workerFrom } from '@transclude/core/worker'; import * as bundle from './dist/server/assets.js'; import * as entry from './dist/server/entry.js'; import manifest from './dist/routes.json'; import config from './transclude.config.js'; export default workerFrom({ config, manifest, entry, bundle }); ``` -------------------------------- ### Inline SVG Definition Source: https://transclude.dev/blog/svg-already-does-transclusion An example of inlining an SVG shape directly, which leads to duplication and maintenance issues compared to using . ```html ``` -------------------------------- ### Implement a server-side loader Source: https://transclude.dev/docs/routing Use the

    ${person.name}

    ``` -------------------------------- ### Project Directory Structure Source: https://transclude.dev/docs/project-layout The standard directory layout for the application, defining roles for routes, elements, icons, and public assets. ```text app/ routes/ .html is a page, .js is an endpoint _layout.html wraps this directory and below index.html / about.html /about people/ [name].html /people/:name docs/ [...path].html /docs/* 404.html 500.html elements/ custom elements, light DOM unless a file asks for a shadow root icons/ one SVG file per icon, compiled to /icons.svg public/ copied to the site root styles/ global.css server.js your own Hono middleware transclude.config.js ``` -------------------------------- ### Configure advanced sitemap with entries and exclusions Source: https://transclude.dev/docs/feeds Use an async function for dynamic entries and provide regex or string patterns for exclusions. ```javascript import { posts } from './app/lib/posts.js'; export default { sitemap: { hostname: 'https://acme.com', entries: async () => (await posts()).map((post) => ({ path: `/posts/${post.slug}`, lastmod: post.date })), exclude: ['/admin', /^\/draft\//], }, }; ``` -------------------------------- ### Define package.json scripts Source: https://transclude.dev/docs/getting-started Standard scripts for development, building, serving, and type-checking. ```json { "scripts": { "dev": "transclude-dev", "build": "transclude-build", "start": "transclude-serve", "check": "transclude-check" } } ``` -------------------------------- ### Conditional Rendering with if, else-if, and else Source: https://transclude.dev/docs/routing Demonstrates conditional rendering where only the first true branch is rendered. ```html

    Searching for ${query}

    Everyone.

    Nobody here yet.

    ``` ```html

    Everyone.

    ``` -------------------------------- ### Define a Route with Server-Side Data Loading Source: https://transclude.dev/docs Use a

    ${person.name}

    Joined ${person.since}

    ``` -------------------------------- ### Enable View Transitions Source: https://transclude.dev/docs/styles Opt into cross-document view transitions by adding the @view-transition rule to both documents. ```css @view-transition { navigation: auto; } @media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } } ``` -------------------------------- ### Enable Precaching in Configuration Source: https://transclude.dev/docs/production Set the precache property to true in the configuration file to generate a manifest of build assets. ```javascript // transclude.config.js export default { precache: true, }; ``` -------------------------------- ### Implement a layout guard Source: https://transclude.dev/docs/layouts Return a Response from a layout loader to stop execution and redirect users, useful for authentication checks. ```javascript export default async ({ cookies, url }) => { const session = await cookies.signed.get('session'); if (!session) return Response.redirect(new URL('/login', url), 303); return { user: await load(session) }; }; ``` -------------------------------- ### Configure test environment Source: https://transclude.dev/docs/testing Ensure environment variables are available during tests by either passing the env-file flag or setting defaults before imports. ```json { "scripts": { "test": "node --test --env-file-if-exists=.env \"test/**/*.test.js\"" } } ``` ```javascript // Before the first import, because the config reads it as it loads. process.env.COOKIE_SECRET ??= 'a-secret-for-tests-only'; ``` -------------------------------- ### Layout directory structure Source: https://transclude.dev/docs/layouts Layouts nest based on the file system structure, where subdirectories inherit from parent layouts. ```text app/routes/ _layout.html wraps everything index.html docs/ _layout.html wraps /docs and below, inside the one above routing.html /docs/routing ``` -------------------------------- ### Define dynamic resource endpoints Source: https://transclude.dev/docs/endpoints Uses bracketed segments in filenames to capture parameters in ctx.params for dynamic resource handling. ```javascript // app/routes/api/people/[id].js import { people } from '../../../data/people.js'; export const GET = ({ params }) => { const person = people.find((p) => p.id === params.id); if (!person) return Response.json({ error: 'not found' }, { status: 404 }); return Response.json(person); }; export const PATCH = async ({ params, request }) => { const person = people.find((p) => p.id === params.id); if (!person) return Response.json({ error: 'not found' }, { status: 404 }); Object.assign(person, await request.json()); return Response.json(person); }; export const DELETE = ({ params }) => { const at = people.findIndex((p) => p.id === params.id); if (at === -1) return Response.json({ error: 'not found' }, { status: 404 }); people.splice(at, 1); return new Response(null, { status: 204 }); }; ``` -------------------------------- ### Style Light and Shadow Elements Source: https://transclude.dev/docs/styles Use :scope for light elements and :host for shadow elements to style the component container. ```css /* app/elements/site-note.html, light */ :scope { display: block; } /* app/elements/user-card.html, shadow = true */ :host { display: block; } :host([compact]) { padding: 0; } ``` -------------------------------- ### Read Request Body Methods Source: https://transclude.dev/docs/endpoints Demonstrates the available methods to parse incoming request bodies. Note that a body can only be read once. ```javascript await request.json(); // parsed JSON await request.formData(); // a form post or an upload await request.text(); // the bytes as they arrived await request.arrayBuffer(); // the bytes themselves ``` -------------------------------- ### Configure transclude.config.js Source: https://transclude.dev/docs/getting-started Defines the directory structure and output paths for the application. ```javascript export default { appDir: 'app', routesDir: 'routes', elementsDir: 'elements', stylesheet: 'app/styles/global.css', publicDir: 'public', outDir: 'dist', }; ``` -------------------------------- ### Define a route with server-side logic and fragments Source: https://transclude.dev/ Use a Notes
    • ${note.text}
    ``` -------------------------------- ### Animate a dialog transition Source: https://transclude.dev/docs/recipes Apply starting-style and allow-discrete to enable smooth transitions for dialog elements. ```css #prefs { opacity: 0; transition: opacity .15s, overlay .15s allow-discrete, display .15s allow-discrete; } #prefs:open { opacity: 1; } @starting-style { #prefs:open { opacity: 0; } } ``` -------------------------------- ### Conditionally load build artifacts Source: https://transclude.dev/docs/testing Check for the existence of build files before importing the production app to allow tests to skip gracefully if the project is not built. ```javascript import fs from 'node:fs'; const built = fs.existsSync('dist/routes.json'); const describe = built ? test : test.skip; const { app } = built ? await import('transclude/production') : { app: null }; ``` -------------------------------- ### Load data for a page Source: https://transclude.dev/docs/recipes Use a server-side script block to export an async function that returns data for the template. ```html
    • ${note.text}
    ``` -------------------------------- ### Configure Sitemap and Feed Source: https://transclude.dev/docs/recipes Defines sitemap and RSS feed generation settings in the project configuration file. ```javascript // transclude.config.js export default { sitemap: { hostname: 'https://example.com' }, feed: { hostname: 'https://example.com', title: 'Notes', items: () => notes.all().map((note) => ({ title: note.title, path: `/notes/${note.slug}`, date: note.written, })), }, }; ``` -------------------------------- ### Define properties and state Source: https://transclude.dev/docs/elements Use script blocks to define external properties and internal reactive state for an element. ```html ${n} ${label} ``` -------------------------------- ### Define server-side data and markup in a single HTML file Source: https://transclude.dev/docs/why Use a script server block to fetch data and an each attribute to iterate over it directly within the HTML structure. ```html

    Posts

    ``` -------------------------------- ### Manage cookies in routes Source: https://transclude.dev/docs/recipes Demonstrates reading from and writing to cookies, including redirecting after form submission. ```javascript export default async ({ cookies }) => ({ theme: cookies.get('theme') ?? 'auto', }); export const POST = async ({ cookies, request, url }) => { const form = await request.formData(); cookies.set('theme', String(form.get('theme')), { maxAge: 31536000 }); return Response.redirect(new URL(url), 303); }; ``` -------------------------------- ### Execute background tasks with ctx.after Source: https://transclude.dev/docs/runtimes Use after to trigger non-blocking operations like analytics or logging. Ensure prerender is set to false as background work cannot outlive a prerendered page. ```javascript // app/routes/notes.html import { recordView } from '../lib/analytics.js'; export const prerender = false; export default async ({ after, url }) => { const { results } = await bindings().DB.prepare('select id, title from notes').all(); // The reader is served without waiting for this. after(recordView(url)); return { notes: results }; }; ``` -------------------------------- ### Configure Proxy Limits Source: https://transclude.dev/docs/includes Defines the configuration object for proxy behavior, including allowlists, size limits, and timeouts. ```javascript proxy: { allow: ['developer.mozilla.org'], maxBytes: 5 * 1024 * 1024, timeout: 10_000, redirects: 5, maxAge: 60_000, sanitize: true, styles: 'keep', } ``` -------------------------------- ### External Content Transclusion with Fallback Source: https://transclude.dev/docs/includes Demonstrates including external content with a fallback paragraph and manual attribution. ```html

    The reference could not be read just now.

    From HTML: HyperText Markup Language on MDN, CC BY-SA 2.5.

    ``` -------------------------------- ### Style icons with CSS Source: https://transclude.dev/docs/icons Icons inherit color and size from the surrounding text context. ```css button { color: #3b3bb0; font-size: 1.25rem; } ``` -------------------------------- ### Handle boolean and array attributes Source: https://transclude.dev/docs/decisions Demonstrates how boolean values and arrays are serialized into HTML attributes. ```html ``` -------------------------------- ### Redirect instead of rendering Source: https://transclude.dev/docs/recipes Return a Response object from the loader to perform a redirect instead of rendering the page. ```javascript export default async ({ url }) => Response.redirect(new URL('/notes', url), 308); ``` -------------------------------- ### List Iteration with each Source: https://transclude.dev/docs/routing Repeats elements for each item in a list, optionally including an index. ```html
  • ${tag}
  • ``` ```html
  • ${i + 1}. ${tag}
  • ``` ```html
  • 1. notes
  • 2. ideas
  • ``` ```html

    ${group.name}

    ${person.name}, ${group.name}
    ``` ```html

    No tags yet.

    • ${tag}
    ``` -------------------------------- ### Manage HTML Block Parsing Source: https://transclude.dev/docs/markdown Demonstrates how blank lines affect whether content inside HTML tags is parsed as Markdown or treated as a raw block. ```html **Four asterisks.** The whole thing is one raw block. **Bold.** The blank line above ended the block. ``` -------------------------------- ### cookies.all() Source: https://transclude.dev/docs/cookies Retrieves all cookies. ```APIDOC ## cookies.all() ### Description Retrieves every cookie as a null-prototype object. ``` -------------------------------- ### Run TypeScript check Source: https://transclude.dev/docs/types Execute the TypeScript validation process for the project. ```bash npm run check ``` -------------------------------- ### Define a Light DOM Custom Element Source: https://transclude.dev/docs/elements Create a custom element by defining properties and styles in an .html file. The element renders directly into the page's DOM. ```html

    Nothing to say.

    ``` ```html Rendered into the page's own DOM. ``` -------------------------------- ### Configure Proxy Allowlist Source: https://transclude.dev/docs/includes Defines allowed hosts for transclusion to prevent unauthorized external requests. ```javascript export default { proxy: { allow: ['developer.mozilla.org', '*.docs.example'], }, }; ``` -------------------------------- ### cookies.signed.set(name, value, options) Source: https://transclude.dev/docs/cookies Signs and writes a cookie. ```APIDOC ## cookies.signed.set(name, value, options) ### Description Signs the provided value and writes it as a cookie. ### Parameters - **name** (string) - Required - The name of the cookie. - **value** (string) - Required - The value to sign and store. - **options** (object) - Optional - Cookie configuration options. ``` -------------------------------- ### Precache Manifest Structure Source: https://transclude.dev/docs/production The generated precache.json file contains a version identifier and a list of URLs with their respective revision hashes. ```json { "version": "W7iCxtYtqwA1rs8Km1_Q", "precache": [ { "url": "/", "revision": "\"SW31_otlz89gCCAy9nsG\"" }, { "url": "/about", "revision": "\"rJtbpeVmJUvYVX743pJQ\"" }, { "url": "/assets/__global-D-s_wVdY.css", "revision": null }, { "url": "/posts/written-once", "revision": "\"lR9y0x_Sq3LhIC5Sq-yW\"" } ] } ``` -------------------------------- ### Configure Markdown Parser Source: https://transclude.dev/docs/markdown Define a custom Markdown parser in the configuration file by providing a function that converts source text to HTML. ```javascript // transclude.config.js import { Marked } from 'marked'; const marked = new Marked(); export default { markdown: (source, file) => marked.parse(source), }; ``` -------------------------------- ### Maintaining State with key Source: https://transclude.dev/docs/routing Uses a unique identifier to track items during re-renders, preserving focus and input state. ```html
  • ``` -------------------------------- ### Define route types with JSDoc Source: https://transclude.dev/docs/types Use JSDoc annotations within a server script block to define parameter types for route loaders. ```html ``` -------------------------------- ### Define head tags in routes Source: https://transclude.dev/docs/routing Top-level tags like title, meta, and link are automatically moved to the document head. ```html ${person.name}

    ${person.name}

    ``` -------------------------------- ### Configure Atom 1.0 feed Source: https://transclude.dev/docs/feeds Set the format to 'atom' and provide required author information. ```javascript feed: { hostname: 'https://acme.com', title: 'Acme', format: 'atom', author: { name: 'Ada Lovelace' }, path: '/atom.xml', items: async () => [], } ``` -------------------------------- ### Apply Dynamic View Transition Names Source: https://transclude.dev/docs/styles Assign unique view-transition-name values to elements using data-driven identifiers. ```html … ``` -------------------------------- ### Configuring fragment header Source: https://transclude.dev/docs/fragments Define the fragment header in the configuration to allow htmx to automatically handle fragment requests. ```javascript fragmentHeader: 'HX-Target', ``` -------------------------------- ### Manage Environment Bindings via Global Registry Source: https://transclude.dev/docs/runtimes Uses a global symbol to store and retrieve environment bindings, ensuring they are accessible within the workerd runtime. ```javascript // app/lib/bindings.js // // Nothing from `node:` here. A loader importing this puts it in the bundle // workerd loads, and that runtime has none of it. // A symbol in the global registry, not a module variable. Two bundlers touch // this file in a transclude app: the build inlines a copy into the server // bundle, and wrangler bundles `worker.js` with a second one. `hold` wrote to // one and `bindings` read the other, so a loader saw nothing and a live signup // went into a fallback instead of the database. const SLOT = Symbol.for('app.bindings'); export const hold = (env) => { globalThis[SLOT] = env; }; export const bindings = () => { const current = globalThis[SLOT]; // Named rather than left to fail on a property of null, which reads like a // missing binding instead of a missing runtime. if (!current) throw new Error('No bindings: this app is running off workerd.'); return current; }; ``` ```javascript // worker.js import { hold } from './app/lib/bindings.js'; function appFor(env) { // Outside the `??=`, because that runs once and this is free to repeat. hold(env); app ??= createApp({ /* … */ }); return app; } ``` ```javascript // app/routes/notes.html import { bindings } from '../lib/bindings.js'; export default async () => { const { results } = await bindings().DB.prepare('select id, title from notes').all(); return { notes: results }; }; ``` -------------------------------- ### Open a dialog without JavaScript Source: https://transclude.dev/docs/recipes Use the command and commandfor attributes to trigger dialog interactions natively. ```html

    Preferences

    ``` -------------------------------- ### Return a Response object Source: https://transclude.dev/docs/routing Returning a Response object from a loader skips the default render process. ```javascript export default async ({ params }) => { const person = find(params.name); if (!person) return new Response('no such person', { status: 404 }); return { person }; }; ``` -------------------------------- ### Render Trusted Markup with html() Source: https://transclude.dev/docs/security Use the html() function to render trusted markup, bypassing automatic escaping. ```html

    ${html(post.renderedMarkdown)}

    ``` -------------------------------- ### Configure CSP directives Source: https://transclude.dev/docs/security Define custom CSP directives by passing an object to the configuration. Use 'hashes' to inject page-specific digests into selected directives. ```javascript csp: { directives: { 'default-src': ["'self'"], 'script-src': ["'self'", "'hashes'"], 'style-src': ["'self'", "'unsafe-inline'"], 'img-src': ["'self'", 'data:', 'https://cdn.example.com'], 'connect-src': ["'self'", 'https://api.example.com'], 'object-src': ["'none'"], 'frame-ancestors': ["'self'"], }, }, ``` -------------------------------- ### Fetching a fragment via JavaScript Source: https://transclude.dev/docs/fragments Use the fetch API to retrieve a fragment and update the DOM using setHTMLUnsafe. ```javascript const res = await fetch('/?q=ada&fragment=matches'); document.getElementById('matches').setHTMLUnsafe(await res.text()); ``` -------------------------------- ### Configure global middleware Source: https://transclude.dev/docs/recipes Applies Hono middleware to specific paths in the server configuration. ```javascript // app/server.js export default (app) => { app.use('/admin/*', async (c, next) => { await next(); c.res.headers.set('x-robots-tag', 'noindex'); }); }; ``` -------------------------------- ### Test a page response Source: https://transclude.dev/docs/testing Use the app.request method to simulate a browser request and verify the response status and content. ```javascript import test from 'node:test'; import assert from 'node:assert/strict'; import { app } from '@transclude/core/production'; test('the notes page answers', async () => { const res = await app.request('http://localhost/notes'); assert.equal(res.status, 200); assert.match(await res.text(), /

    { const person = find(params.name); if (!person) response.status = 404; return { person }; }; ``` -------------------------------- ### Guard routes with layout loaders Source: https://transclude.dev/docs/recipes Uses a layout loader to verify session cookies and redirect unauthorized users before rendering child content. ```html ``` -------------------------------- ### Define HTML Templates Source: https://transclude.dev/blog/two-templates-one-thing Two separate template files containing identical markup for rendering search results. ```html ``` ```html ``` -------------------------------- ### Verify Template Consistency Source: https://transclude.dev/blog/two-templates-one-thing Asserts that the fragment returned by an endpoint is a literal substring of the full page content to ensure template synchronization. ```javascript const whole = await text('/?q=form'); const fragment = (await text('/?q=form&fragment=results')).trim(); assert.ok(whole.includes(fragment)); ``` -------------------------------- ### Implement custom middleware in app/server.js Source: https://transclude.dev/docs/middleware Adds a custom header to all requests by utilizing the Hono instance's use method. ```javascript // app/server.js export default (app) => { app.use('*', async (c, next) => { c.header('X-Frame-Options', 'DENY'); await next(); }); }; ``` -------------------------------- ### Create a reusable element Source: https://transclude.dev/docs/recipes Define custom elements with properties and scoped styles to maintain clean, reusable components. ```html

    ${title}

    ```