Fresh Documentation

website·Indexed 33 days ago

https://usefresh.dev/docs/introduction

Documentation for Fresh, a web framework for Deno. Includes guides on islands for client-side interactivity, file-based routing, signals for state management, and deployment options for Deno Deploy, Cloudflare Workers, and Docker. Covers advanced features like OpenTelemetry, WebSockets, view transitions, and partials, as well as built-in plugins for CSRF and CSP.

Tokens
32.2K
Snippets
203
Records
249
Agent score
69%

What's inside Fresh

  1. Overview of Fresh OpenTelemetry instrumentation

    Fresh automatically instruments key operations using the @opentelemetry/api package. Spans are created under the fresh tracer (named with the current Fresh version). If no exporter is configured, spans are silently discarded with no performance overhead.

    Fresh creates spans for the following operations:

    • Middleware execution (each middleware in the chain)
    • Route handler execution
    • Server-side rendering (including async components)
    • Static file serving (lookups, caching, and responses)
    • Lazy route loading (dynamic imports of route modules on first access)
  2. Overview of the Fresh Context instance

    The Context instance is shared across all middlewares in Fresh. It provides a unified way to access request metadata, the incoming Request, the resolved application configuration, and helper methods for responding with HTML or triggering redirects.
  3. Understand how Fresh handles active links with aria-current

    Fresh automatically adds the aria-current attribute to <a> elements to improve accessibility by indicating the current page to assistive technologies.

    • aria-current="page": Added when the link's path is an exact match for the current URL.
    • aria-current="true": Added to ancestor links (e.g., a link to /docs when the current page is /docs/intro).

    If a developer manually sets the aria-current attribute on an <a> element, Fresh will not overwrite it, allowing for custom state management or integration with third-party component libraries.

  4. Fresh framework overview and use cases

    Fresh is a fast, extensible full-stack web framework built on Web Standards and Deno. It utilizes 'Island Architecture', rendering server-generated HTML and only shipping JavaScript for interactive components.

    Ideal Use Cases:

    • Server-rendered sites (Home pages, E-commerce, Portfolios, Landing pages, Documentation).
    • Web APIs and CRUD applications.
    • AI-assisted development due to its predictable file-based conventions.

    When NOT to use Fresh:

    • If you are building a Single-Page Application (SPA), Fresh is not the appropriate framework.
  5. Understand Fresh server-first rendering and islands architecture

    Fresh is a server-first web framework where pages are fully rendered to HTML on the server before being sent to the browser. This ensures immediate visibility, SEO compatibility, and functionality without JavaScript. To handle interactivity, Fresh uses an 'islands architecture': only components located in the islands/ directory are hydrated in the browser. All other components remain static HTML, minimizing the amount of JavaScript shipped to the client.
  6. Understand Fresh island prop serialization

    When Fresh renders a page on the server, island props must be serialized to JSON to be sent to the browser for hydration. Fresh uses a custom serialization system that supports a wider range of types than standard JSON.stringify, including circular references.
  7. Understand the Fresh request-response lifecycle

    Fresh operates by receiving a standard Web Request and passing it through a chain of one or more middlewares. The process continues until a middleware returns a Response (such as HTML or JSON). If the response is HTML and contains 'Islands' (interactive Preact components), Fresh boots these components in the browser and executes the associated JavaScript to enable interactivity.
  8. Install or refresh project dependencies

    If Deno complains about missing packages upon first run, or if you suspect cached packages are outdated, use the install command. Use the -r flag to force a clean reinstall of dependencies.
    # Standard installation
    deno install --allow-scripts
    
    # Force clean reinstall
    deno install -r --allow-scripts
  9. Create a new page route

    Fresh uses file-system based routing. To create a new page, add a .tsx file to the routes/ directory. For example, creating routes/about.tsx will make the page available at the /about URL.
    import { define } from "@/utils.ts";
    
    export default define.page(() => {
      return (
        <main>
          <h1>About</h1>
          <p>This is the about page.</p>
        </main>
      );
    });
  10. Understand route matching priority

    Fresh matches routes based on the following priority rules:

    1. Static routes: Exact path matches (e.g., /about) are checked first and always take precedence over dynamic routes.
    2. Dynamic routes: Patterns (e.g., /posts/:id) are checked in the order they were registered. The first matching route wins.

    Because registration order matters for dynamic routes, more specific dynamic routes should be registered before more general ones.

    const app = new App()
      // Checked first: matches exactly /posts/featured
      .get("/posts/featured", () => new Response("Featured posts"))
      // Checked second: matches any other /posts/:id
      .get("/posts/:id", (ctx) => new Response(`Post: ${ctx.params.id}`));
  11. Nest Islands within other Islands

    Islands can be nested inside other islands. In this scenario, they behave like normal Preact components but still receive serialized props if provided. This allows for optimal mixing of static and interactive parts of the application, ensuring only the necessary JavaScript is sent to the browser.
    // islands/other-island.tsx
    export default (props: { foo: string }) => <>{props.foo}</>;
    
    // routes/index.tsx
    import MyIsland from "../islands/my-island.tsx";
    import OtherIsland from "../islands/other-island.tsx";
    
    <MyIsland>
      <OtherIsland foo="this prop will be serialized" />
    </MyIsland>
  12. Integrate third-party Web Component libraries

    Third-party web components are integrated by importing their registration scripts inside an island's useEffect hook. It is recommended to return a plain HTML fallback in the !IS_BROWSER branch so the page remains usable before JavaScript loads.
    import { useEffect } from "preact/hooks";
    import { IS_BROWSER } from "fresh/runtime";
    
    export function ShoelaceButton() {
      useEffect(() => {
        import("@shoelace-style/shoelace/dist/components/button/button.js");
      }, []);
    
      if (!IS_BROWSER) {
        return <button>Click me</button>; // HTML fallback
      }
    
      return <sl-button variant="primary">Click me</sl-button>;
    }