Full Code of denoland/fresh for AI

main 4cc76aefed73 cached
485 files
1.3 MB
367.9k tokens
849 symbols
1 requests
Download .txt
Showing preview only (1,446K chars total). Download the full file or copy to clipboard to get everything.
Repository: denoland/fresh
Branch: main
Commit: 4cc76aefed73
Files: 485
Total size: 1.3 MB

Directory structure:
gitextract__i6wh6to/

├── .gitattributes
├── .github/
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       ├── deploy.yml
│       ├── post_publish.yml
│       └── publish.yml
├── .gitignore
├── .vscode/
│   ├── extensions.json
│   ├── settings.json
│   └── tailwind.json
├── LICENSE
├── README.md
├── _typos.toml
├── deno.json
├── docs/
│   ├── 1.x/
│   │   ├── concepts/
│   │   │   ├── ahead-of-time-builds.md
│   │   │   ├── app-wrapper.md
│   │   │   ├── architecture.md
│   │   │   ├── data-fetching.md
│   │   │   ├── deployment.md
│   │   │   ├── error-pages.md
│   │   │   ├── forms.md
│   │   │   ├── index.md
│   │   │   ├── islands.md
│   │   │   ├── layouts.md
│   │   │   ├── middleware.md
│   │   │   ├── partials.md
│   │   │   ├── plugins.md
│   │   │   ├── routes.md
│   │   │   ├── routing.md
│   │   │   ├── server-components.md
│   │   │   ├── server-configuration.md
│   │   │   ├── static-files.md
│   │   │   └── updating.md
│   │   ├── examples/
│   │   │   ├── active-links.md
│   │   │   ├── authentication-with-supabase.md
│   │   │   ├── changing-the-src-dir.md
│   │   │   ├── client-side-components-and-libraries.md
│   │   │   ├── creating-a-crud-api.md
│   │   │   ├── dealing-with-cors.md
│   │   │   ├── handling-complex-routes.md
│   │   │   ├── index.md
│   │   │   ├── init-the-server.md
│   │   │   ├── migrating-to-tailwind.md
│   │   │   ├── modifying-the-head.md
│   │   │   ├── rendering-markdown.md
│   │   │   ├── rendering-raw-html.md
│   │   │   ├── setting-the-language.md
│   │   │   ├── sharing-state-between-islands.md
│   │   │   ├── using-csp.md
│   │   │   ├── using-fresh-canary-version.md
│   │   │   ├── using-twind-v1.md
│   │   │   └── writing-tests.md
│   │   ├── getting-started/
│   │   │   ├── adding-interactivity.md
│   │   │   ├── create-a-project.md
│   │   │   ├── create-a-route.md
│   │   │   ├── custom-handlers.md
│   │   │   ├── deploy-to-production.md
│   │   │   ├── dynamic-routes.md
│   │   │   ├── form-submissions.md
│   │   │   ├── index.md
│   │   │   └── running-locally.md
│   │   ├── integrations/
│   │   │   └── index.md
│   │   └── introduction/
│   │       └── index.md
│   ├── canary/
│   │   └── the-canary-version/
│   │       └── index.md
│   ├── latest/
│   │   ├── advanced/
│   │   │   ├── app-wrapper.md
│   │   │   ├── builder.md
│   │   │   ├── define.md
│   │   │   ├── environment-variables.md
│   │   │   ├── error-handling.md
│   │   │   ├── forms.md
│   │   │   ├── head.md
│   │   │   ├── index.md
│   │   │   ├── layouts.md
│   │   │   ├── partials.md
│   │   │   ├── troubleshooting.md
│   │   │   └── vite.md
│   │   ├── concepts/
│   │   │   ├── app.md
│   │   │   ├── context.md
│   │   │   ├── file-routing.md
│   │   │   ├── index.md
│   │   │   ├── islands.md
│   │   │   ├── layouts.md
│   │   │   ├── middleware.md
│   │   │   ├── routing.md
│   │   │   └── static-files.md
│   │   ├── deployment/
│   │   │   ├── cloudflare-workers.md
│   │   │   ├── deno-compile.md
│   │   │   ├── deno-deploy.md
│   │   │   ├── docker.md
│   │   │   └── index.md
│   │   ├── examples/
│   │   │   ├── active-links.md
│   │   │   ├── daisyui.md
│   │   │   ├── markdown.md
│   │   │   ├── migration-guide.md
│   │   │   ├── rendering-raw-html.md
│   │   │   └── sharing-state-between-islands.md
│   │   ├── getting-started/
│   │   │   └── index.md
│   │   ├── introduction/
│   │   │   └── index.md
│   │   ├── plugins/
│   │   │   ├── cors.md
│   │   │   ├── csp.md
│   │   │   ├── csrf.md
│   │   │   ├── index.md
│   │   │   └── trailing-slashes.md
│   │   └── testing/
│   │       └── index.md
│   └── toc.ts
├── packages/
│   ├── build-id/
│   │   ├── README.md
│   │   ├── deno.json
│   │   └── mod.ts
│   ├── examples/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── deno.json
│   │   └── src/
│   │       ├── app1.tsx
│   │       ├── app2.tsx
│   │       ├── island.tsx
│   │       └── shared.tsx
│   ├── fresh/
│   │   ├── README.md
│   │   ├── deno.json
│   │   ├── src/
│   │   │   ├── app.ts
│   │   │   ├── app_test.tsx
│   │   │   ├── build_cache.ts
│   │   │   ├── commands.ts
│   │   │   ├── compat.ts
│   │   │   ├── compat_test.tsx
│   │   │   ├── config.ts
│   │   │   ├── config_test.ts
│   │   │   ├── constants.ts
│   │   │   ├── context.ts
│   │   │   ├── context_test.tsx
│   │   │   ├── define.ts
│   │   │   ├── define_test.ts
│   │   │   ├── dev/
│   │   │   │   ├── builder.ts
│   │   │   │   ├── builder_test.ts
│   │   │   │   ├── check.ts
│   │   │   │   ├── dev_build_cache.ts
│   │   │   │   ├── dev_build_cache_test.ts
│   │   │   │   ├── esbuild.ts
│   │   │   │   ├── file_transformer.ts
│   │   │   │   ├── file_transformer_test.ts
│   │   │   │   ├── fs_crawl.ts
│   │   │   │   ├── fs_crawl_test.ts
│   │   │   │   ├── middlewares/
│   │   │   │   │   ├── automatic_workspace_folders.ts
│   │   │   │   │   ├── error_overlay/
│   │   │   │   │   │   ├── code_frame.ts
│   │   │   │   │   │   ├── middleware.tsx
│   │   │   │   │   │   ├── middleware_test.tsx
│   │   │   │   │   │   └── overlay.tsx
│   │   │   │   │   └── live_reload.ts
│   │   │   │   ├── mod.ts
│   │   │   │   ├── update_check.ts
│   │   │   │   └── update_check_test.ts
│   │   │   ├── error.ts
│   │   │   ├── error_test.ts
│   │   │   ├── file_url.ts
│   │   │   ├── file_url_test.ts
│   │   │   ├── fs.ts
│   │   │   ├── fs_routes.ts
│   │   │   ├── fs_routes_test.tsx
│   │   │   ├── handlers.ts
│   │   │   ├── internals.ts
│   │   │   ├── internals_dev.ts
│   │   │   ├── jsonify/
│   │   │   │   ├── __snapshots__/
│   │   │   │   │   └── round_trip_test.ts.snap
│   │   │   │   ├── constants.ts
│   │   │   │   ├── custom_test.ts
│   │   │   │   ├── parse.ts
│   │   │   │   ├── round_trip_test.ts
│   │   │   │   ├── stringify.ts
│   │   │   │   └── stringify_test.ts
│   │   │   ├── middlewares/
│   │   │   │   ├── cors.ts
│   │   │   │   ├── cors_test.ts
│   │   │   │   ├── csp.ts
│   │   │   │   ├── csp_test.ts
│   │   │   │   ├── csrf.ts
│   │   │   │   ├── csrf_test.ts
│   │   │   │   ├── mod.ts
│   │   │   │   ├── mod_test.ts
│   │   │   │   ├── static_files.ts
│   │   │   │   ├── static_files_test.ts
│   │   │   │   ├── trailing_slashes.ts
│   │   │   │   └── trailing_slashes_test.ts
│   │   │   ├── mod.ts
│   │   │   ├── otel.ts
│   │   │   ├── render.ts
│   │   │   ├── router.ts
│   │   │   ├── router_test.ts
│   │   │   ├── runtime/
│   │   │   │   ├── client/
│   │   │   │   │   ├── dev.ts
│   │   │   │   │   ├── mod.ts
│   │   │   │   │   ├── partials.ts
│   │   │   │   │   ├── polyfills.ts
│   │   │   │   │   ├── preact_hooks_client.ts
│   │   │   │   │   └── reviver.ts
│   │   │   │   ├── head.ts
│   │   │   │   ├── server/
│   │   │   │   │   └── preact_hooks.ts
│   │   │   │   ├── shared.ts
│   │   │   │   └── shared_internal.ts
│   │   │   ├── segments.ts
│   │   │   ├── segments_test.ts
│   │   │   ├── server/
│   │   │   │   └── tailwind_aot_error_page.tsx
│   │   │   ├── test_utils.ts
│   │   │   ├── types.ts
│   │   │   ├── utils.ts
│   │   │   └── utils_test.ts
│   │   └── tests/
│   │       ├── active_links_test.tsx
│   │       ├── doc_examples_test.tsx
│   │       ├── fixture_head/
│   │       │   ├── islands/
│   │       │   │   ├── MetaIsland.tsx
│   │       │   │   ├── StyleIdIsland.tsx
│   │       │   │   ├── TemplateIsland.tsx
│   │       │   │   └── TitleIsland.tsx
│   │       │   └── routes/
│   │       │       ├── _app.tsx
│   │       │       ├── id.tsx
│   │       │       ├── key.tsx
│   │       │       ├── meta.tsx
│   │       │       └── title.tsx
│   │       ├── fixture_island_groups/
│   │       │   └── routes/
│   │       │       ├── both/
│   │       │       │   ├── (_islands)/
│   │       │       │   │   └── Foo.tsx
│   │       │       │   └── index.tsx
│   │       │       ├── foo/
│   │       │       │   ├── (_islands)/
│   │       │       │   │   └── Foo.tsx
│   │       │       │   └── index.tsx
│   │       │       └── index.tsx
│   │       ├── fixture_precompile/
│   │       │   ├── invalid/
│   │       │   │   ├── deno.json
│   │       │   │   ├── dev.ts
│   │       │   │   └── main.tsx
│   │       │   └── valid/
│   │       │       ├── deno.json
│   │       │       └── main.tsx
│   │       ├── fixture_update_check/
│   │       │   └── mod.ts
│   │       ├── fixtures_islands/
│   │       │   ├── Computed.tsx
│   │       │   ├── Counter.tsx
│   │       │   ├── CounterWithSlots.tsx
│   │       │   ├── EnvIsland.tsx
│   │       │   ├── EscapeIsland.tsx
│   │       │   ├── FnIsland.tsx
│   │       │   ├── FragmentIsland.tsx
│   │       │   ├── FreshAttrs.tsx
│   │       │   ├── IslandInIsland.tsx
│   │       │   ├── JsonIsland.tsx
│   │       │   ├── JsxChildrenIsland.tsx
│   │       │   ├── JsxConditional.tsx
│   │       │   ├── JsxIsland.tsx
│   │       │   ├── Multiple.tsx
│   │       │   ├── NodeProcess.tsx
│   │       │   ├── NullIsland.tsx
│   │       │   ├── OptOutPartialLink.tsx
│   │       │   ├── PartialInIsland.tsx
│   │       │   ├── PassThrough.tsx
│   │       │   ├── SelfCounter.tsx
│   │       │   └── data.json
│   │       ├── head_test.tsx
│   │       ├── islands_test.tsx
│   │       ├── lorem_ipsum.txt
│   │       ├── partials_test.tsx
│   │       ├── precompile_test.ts
│   │       └── test_utils.tsx
│   ├── init/
│   │   ├── README.md
│   │   ├── deno.json
│   │   └── src/
│   │       ├── init.ts
│   │       ├── init_test.ts
│   │       └── mod.ts
│   ├── plugin-tailwindcss/
│   │   ├── README.md
│   │   ├── deno.json
│   │   └── src/
│   │       ├── mod.ts
│   │       └── types.ts
│   ├── plugin-tailwindcss-v3/
│   │   ├── README.md
│   │   ├── deno.json
│   │   └── src/
│   │       └── mod.ts
│   ├── plugin-vite/
│   │   ├── README.md
│   │   ├── demo/
│   │   │   ├── assets/
│   │   │   │   └── style.css
│   │   │   ├── client.ts
│   │   │   ├── components/
│   │   │   │   ├── CssModuleNonIsland.tsx
│   │   │   │   └── CssModulesNonIsland.module.css
│   │   │   ├── fixtures/
│   │   │   │   ├── commonjs_mod.cjs
│   │   │   │   └── maxmind.cjs
│   │   │   ├── islands/
│   │   │   │   ├── Bar.tsx
│   │   │   │   ├── CssModules.module.css
│   │   │   │   ├── CssModules.tsx
│   │   │   │   ├── CssModulesOther.module.css
│   │   │   │   ├── CssModulesOther.tsx
│   │   │   │   ├── Foo.tsx
│   │   │   │   ├── IslandNestedInner.tsx
│   │   │   │   ├── IslandNestedOuter.tsx
│   │   │   │   └── tests/
│   │   │   │       ├── CounterHooks.tsx
│   │   │   │       ├── EnvIsland.tsx
│   │   │   │       ├── IslandAssets.tsx
│   │   │   │       ├── Mime.tsx
│   │   │   │       └── Ready.tsx
│   │   │   ├── main.ts
│   │   │   ├── routes/
│   │   │   │   ├── _error.tsx
│   │   │   │   ├── about.tsx
│   │   │   │   ├── index.tsx
│   │   │   │   └── tests/
│   │   │   │       ├── CssRoute.module.css
│   │   │   │       ├── api/
│   │   │   │       │   └── [id].tsx
│   │   │   │       ├── assets.tsx
│   │   │   │       ├── build_id.tsx
│   │   │   │       ├── commonjs.tsx
│   │   │   │       ├── css.tsx
│   │   │   │       ├── css_modules.tsx
│   │   │   │       ├── css_styles.css
│   │   │   │       ├── dep_json.tsx
│   │   │   │       ├── env.tsx
│   │   │   │       ├── env_files.tsx
│   │   │   │       ├── feed.tsx
│   │   │   │       ├── ioredis.tsx
│   │   │   │       ├── island_assets.tsx
│   │   │   │       ├── island_hooks.tsx
│   │   │   │       ├── island_nested.tsx
│   │   │   │       ├── it_works.tsx
│   │   │   │       ├── jsx_namespace.tsx
│   │   │   │       ├── maxmind.tsx
│   │   │   │       ├── middlewares/
│   │   │   │       │   ├── _middleware.ts
│   │   │   │       │   └── index.tsx
│   │   │   │       ├── mime.tsx
│   │   │   │       ├── partial.tsx
│   │   │   │       ├── partial_insert.tsx
│   │   │   │       ├── pg.tsx
│   │   │   │       ├── qs.tsx
│   │   │   │       ├── radix.tsx
│   │   │   │       ├── redis.tsx
│   │   │   │       ├── remote_island.tsx
│   │   │   │       ├── stripe.tsx
│   │   │   │       ├── supabase_pg.tsx
│   │   │   │       ├── tailwind.tsx
│   │   │   │       └── throw.tsx
│   │   │   ├── static/
│   │   │   │   ├── foo.txt
│   │   │   │   └── test_static/
│   │   │   │       ├── foo/
│   │   │   │       │   └── index.html
│   │   │   │       └── foo.txt
│   │   │   ├── utils.ts
│   │   │   └── vite.config.ts
│   │   ├── deno.json
│   │   ├── src/
│   │   │   ├── client.ts
│   │   │   ├── mod.ts
│   │   │   ├── plugins/
│   │   │   │   ├── build_id.ts
│   │   │   │   ├── client_entry.ts
│   │   │   │   ├── client_snapshot.ts
│   │   │   │   ├── deno.ts
│   │   │   │   ├── dev_server.ts
│   │   │   │   ├── patches/
│   │   │   │   │   ├── code_eval.ts
│   │   │   │   │   ├── code_eval_test.ts
│   │   │   │   │   ├── commonjs.ts
│   │   │   │   │   ├── commonjs_test.ts
│   │   │   │   │   ├── http_absolute.ts
│   │   │   │   │   ├── http_absolute_test.ts
│   │   │   │   │   ├── inline_env_vars.ts
│   │   │   │   │   ├── inline_env_vars_test.ts
│   │   │   │   │   ├── jsx_comment.ts
│   │   │   │   │   ├── jsx_comment_test.ts
│   │   │   │   │   ├── remove_polyfills.ts
│   │   │   │   │   └── remove_polyfills_test.ts
│   │   │   │   ├── patches.ts
│   │   │   │   ├── server_entry.ts
│   │   │   │   ├── server_snapshot.ts
│   │   │   │   ├── shims/
│   │   │   │   │   ├── object.entries/
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   └── supports-color/
│   │   │   │   │       └── index.ts
│   │   │   │   ├── shims.ts
│   │   │   │   └── verify_imports.ts
│   │   │   ├── shared.ts
│   │   │   └── utils.ts
│   │   └── tests/
│   │       ├── build_test.ts
│   │       ├── dev_server_test.ts
│   │       ├── fixtures/
│   │       │   ├── deno_global_island/
│   │       │   │   ├── islands/
│   │       │   │   │   └── Foo.tsx
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── deno_global_ssr/
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── island_global_name/
│   │       │   │   ├── deno.json
│   │       │   │   ├── islands/
│   │       │   │   │   └── Map.tsx
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── no_islands/
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── no_routes/
│   │       │   │   ├── main.ts
│   │       │   │   └── vite.config.ts
│   │       │   ├── no_static/
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── node_builtin/
│   │       │   │   ├── islands/
│   │       │   │   │   └── NodeIsland.tsx
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── remote_island/
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── tailwind_app/
│   │       │   │   ├── assets/
│   │       │   │   │   └── style.css
│   │       │   │   ├── client.ts
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   ├── _app.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── tailwind_no_app/
│   │       │   │   ├── assets/
│   │       │   │   │   └── style.css
│   │       │   │   ├── client.ts
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   └── test_files_exclusion/
│   │       │       ├── deno.json
│   │       │       ├── main.ts
│   │       │       ├── routes/
│   │       │       │   ├── foo.test.ts
│   │       │       │   ├── index.tsx
│   │       │       │   └── index_test.tsx
│   │       │       └── vite.config.ts
│   │       └── test_utils.ts
│   └── update/
│       ├── README.md
│       ├── deno.json
│       └── src/
│           ├── mod.ts
│           ├── update.ts
│           ├── update_test.ts
│           └── utils.ts
├── tools/
│   ├── check_docs.ts
│   ├── check_links.ts
│   └── release.ts
├── versions.json
└── www/
    ├── README.md
    ├── assets/
    │   └── styles.css
    ├── client.ts
    ├── components/
    │   ├── CodeBlock.tsx
    │   ├── CodeWindow.tsx
    │   ├── CopyButton.tsx
    │   ├── DocsSidebar.tsx
    │   ├── FancyLink.tsx
    │   ├── FeatureIcons.tsx
    │   ├── Footer.tsx
    │   ├── Header.tsx
    │   ├── Icons.tsx
    │   ├── NavigationBar.tsx
    │   ├── PageSection.tsx
    │   ├── Projects.tsx
    │   ├── SideBySide.tsx
    │   ├── WaveTank.ts
    │   └── homepage/
    │       ├── CTA.tsx
    │       ├── CodeExampleBox.tsx
    │       ├── DemoBox.tsx
    │       ├── DenoSection.tsx
    │       ├── ExampleArrow.tsx
    │       ├── FormsSection.tsx
    │       ├── Hero.tsx
    │       ├── IslandsSection.tsx
    │       ├── PartialsSection.tsx
    │       ├── RecipeDemo.tsx
    │       ├── RenderingSection.tsx
    │       ├── SectionHeading.tsx
    │       ├── Simple.tsx
    │       └── SocialProof.tsx
    ├── data/
    │   ├── docs.ts
    │   └── showcase.json
    ├── deno.json
    ├── dev.ts
    ├── islands/
    │   ├── Counter.tsx
    │   ├── FormSubmitDemo.tsx
    │   ├── LemonBottom.tsx
    │   ├── LemonDrop.tsx
    │   ├── LemonTop.tsx
    │   ├── SearchButton.tsx
    │   ├── TableOfContents.tsx
    │   ├── ThemeToggle.tsx
    │   └── VersionSelect.tsx
    ├── main.ts
    ├── main_test.ts
    ├── routes/
    │   ├── _app.tsx
    │   ├── _error.tsx
    │   ├── _middleware.ts
    │   ├── docs/
    │   │   ├── [...slug].tsx
    │   │   ├── _layout.tsx
    │   │   ├── _middleware.ts
    │   │   └── index.tsx
    │   ├── index.tsx
    │   ├── raw.ts
    │   ├── recipes/
    │   │   ├── _layout.tsx
    │   │   ├── _middleware.ts
    │   │   ├── lemon-honey-tea.tsx
    │   │   ├── lemonade.tsx
    │   │   └── lemondrop.tsx
    │   ├── showcase-bak.tsx
    │   ├── showcase.tsx
    │   ├── thanks.tsx
    │   └── update.tsx
    ├── static/
    │   ├── docsearch.css
    │   ├── google40caa9e535ae39e9.html
    │   ├── markdown.css
    │   └── prism.css
    ├── utils/
    │   ├── markdown.ts
    │   ├── prism.ts
    │   ├── screenshot.ts
    │   ├── screenshot_test.ts
    │   └── state.ts
    └── vite.config.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
# Use Unix line endings in all text files.
* text=auto eol=lf

================================================
FILE: .github/CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity and
orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall
  community

Examples of unacceptable behavior include:

- The use of sexualized language or imagery, and sexual attention or advances of
  any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address,
  without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at hello@lcas.dev.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series of
actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within the
community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by
[Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.


================================================
FILE: .github/CONTRIBUTING.md
================================================
# Contributing Guidelines

## Submitting a pull request

First, please be sure to ensure `deno task ok` is run and successfully passes.


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      # Check for updates to GitHub Actions every week
      interval: "weekly"


================================================
FILE: .github/workflows/ci.yml
================================================
name: ci

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ${{ matrix.os }}
    timeout-minutes: 10

    strategy:
      fail-fast: false
      matrix:
        deno: ["v2.x", "canary"]
        os: [macOS-latest, windows-latest, ubuntu-latest]
        include:
          - os: ubuntu-latest
            cache_path: ~/.cache/deno/
          - os: macos-latest
            cache_path: ~/Library/Caches/deno/
          - os: windows-latest
            cache_path: ~\AppData\Local\deno\

    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Setup Deno
        uses: denoland/setup-deno@v2
        with:
          cache: true
          deno-version: ${{ matrix.deno }}

      - name: Install dependencies
        run: deno install

      - name: Verify formatting
        if: startsWith(matrix.os, 'ubuntu') && matrix.deno == 'v2.x'
        run: deno fmt --check

      - name: Run linter
        if: startsWith(matrix.os, 'ubuntu') && matrix.deno == 'v2.x'
        run: deno lint

      - name: Spell-check
        if: startsWith(matrix.os, 'ubuntu') && matrix.deno == 'v2.x'
        uses: crate-ci/typos@master

      - name: Type check project
        run: deno task check:types

      - name: Run tests
        run: deno task test

      - name: Check docs
        run: deno task check:docs

      - name: Build fresh.deno.dev
        if: startsWith(matrix.os, 'ubuntu') && matrix.deno == 'v2.x'
        run: deno task build-www


================================================
FILE: .github/workflows/deploy.yml
================================================
name: Deploy
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest

    permissions:
      id-token: write # Needed for auth with Deno Deploy
      contents: read # Needed to clone the repository

    steps:
      - name: Clone repository
        uses: actions/checkout@v4

      - name: Install Deno
        uses: denoland/setup-deno@v2
        with:
          cache: true

      - name: Run install step
        run: "deno install"

      - name: Build step
        working-directory: ./www
        run: "deno task build"

      - name: Upload to Deno Deploy
        uses: denoland/deployctl@v1
        # Skip publishing for forks
        if: github.repository_owner == 'denoland'
        with:
          project: "fresh"
          entrypoint: "server.js"
          root: "./www/_fresh/"


================================================
FILE: .github/workflows/post_publish.yml
================================================
name: post_publish

on:
  release:
    types: [published]

jobs:
  update-dl-version:
    name: update dl.deno.land version
    runs-on: ubuntu-22.04
    if: github.repository == 'denoland/fresh'
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Authenticate with Google Cloud
        uses: google-github-actions/auth@v2
        with:
          project_id: denoland
          credentials_json: ${{ secrets.GCP_SA_KEY }}
          export_environment_variables: true
          create_credentials_file: true

      - name: Setup gcloud
        uses: google-github-actions/setup-gcloud@v2
        with:
          project_id: denoland

      - name: Upload version file to dl.deno.land
        run: |
          cat packages/fresh/deno.json | jq -r ".version" > release-latest.txt
          gsutil -h "Cache-Control: no-cache" cp release-latest.txt gs://dl.deno.land/fresh/release-latest.txt


================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish JSR

on:
  push:
    branches:
      - main

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write

    # Skip publishing for forks
    if: github.repository_owner == 'denoland'

    steps:
      - uses: actions/checkout@v4

      - name: Install Deno
        uses: denoland/setup-deno@v2
        with:
          cache: true

      - name: Install dependencies
        run: deno install

      - name: Publish
        run: deno publish


================================================
FILE: .gitignore
================================================
_fresh/
.vite/
vendor/
node_modules/
.docs/
.DS_Store
tmp_*
coverage/
vite-inspect/
.vite-inspect/
demo/dist/

================================================
FILE: .vscode/extensions.json
================================================
{
  "recommendations": [
    "denoland.vscode-deno"
  ]
}


================================================
FILE: .vscode/settings.json
================================================
{
  "deno.enable": true,
  "deno.lint": true,
  "deno.codeLens.test": true,
  "deno.documentPreloadLimit": 2000,
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "denoland.vscode-deno",
  "[typescriptreact]": {
    "editor.defaultFormatter": "denoland.vscode-deno"
  },
  "[typescript]": {
    "editor.defaultFormatter": "denoland.vscode-deno"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "denoland.vscode-deno"
  },
  "[javascript]": {
    "editor.defaultFormatter": "denoland.vscode-deno"
  },
  "[markdown]": {
    "editor.defaultFormatter": "denoland.vscode-deno"
  },
  "css.customData": [
    ".vscode/tailwind.json"
  ],
  "[json]": {
    "editor.defaultFormatter": "denoland.vscode-deno"
  }
}


================================================
FILE: .vscode/tailwind.json
================================================
{
  "version": 1.1,
  "atDirectives": [
    {
      "name": "@tailwind",
      "description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.",
      "references": [
        {
          "name": "Tailwind Documentation",
          "url": "https://tailwindcss.com/docs/functions-and-directives#tailwind"
        }
      ]
    },
    {
      "name": "@apply",
      "description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.",
      "references": [
        {
          "name": "Tailwind Documentation",
          "url": "https://tailwindcss.com/docs/functions-and-directives#apply"
        }
      ]
    },
    {
      "name": "@responsive",
      "description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n  .alert {\n    background-color: #E53E3E;\n  }\n}\n```\n",
      "references": [
        {
          "name": "Tailwind Documentation",
          "url": "https://tailwindcss.com/docs/functions-and-directives#responsive"
        }
      ]
    },
    {
      "name": "@screen",
      "description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n  /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n  /* ... */\n}\n```\n",
      "references": [
        {
          "name": "Tailwind Documentation",
          "url": "https://tailwindcss.com/docs/functions-and-directives#screen"
        }
      ]
    },
    {
      "name": "@variants",
      "description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n   .btn-brand {\n    background-color: #3182CE;\n  }\n}\n```\n",
      "references": [
        {
          "name": "Tailwind Documentation",
          "url": "https://tailwindcss.com/docs/functions-and-directives#variants"
        }
      ]
    }
  ]
}


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2021-2023 Luca Casonato

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
[Documentation](#-documentation) | [Getting started](#-getting-started) |
[API Reference](https://deno.land/x/fresh?doc)

# fresh

<img align="right" src="https://fresh.deno.dev/logo.svg" height="150px" alt="The Fresh logo: a sliced lemon dripping with juice">

**Fresh** is a next generation web framework, built for speed, reliability, and
simplicity.

Some stand-out features:

- Island based client hydration for maximum interactivity.
- Zero runtime overhead: no JS is shipped to the client by default.
- No configuration necessary.
- TypeScript support out of the box.
- File-system routing à la Next.js.

## 📖 Documentation

The [documentation](https://fresh.deno.dev/docs/introduction) is available on
[fresh.deno.dev](https://fresh.deno.dev/).

## 🚀 Getting started

Install the latest [Deno CLI](https://deno.com/) version.

You can scaffold a new project by running the Fresh init script. To scaffold a
project run the following:

```sh
deno run -Ar jsr:@fresh/init
```

Then navigate to the newly created project folder:

```
cd fresh-project
```

From within your project folder, start the development server using the
`deno task` command:

```
deno task dev
```

Now open http://localhost:5173 in your browser to view the page. You make
changes to the project source code and see them reflected in your browser.

To deploy the project to the live internet, you can use
[Deno Deploy](https://deno.com/deploy):

1. Push your project to GitHub.
2. [Create a Deno Deploy project.](https://console.deno.com/new)
3. Select your GitHub repository.
4. The project will be deployed to a public $project.$username.deno.net
   subdomain with no configuration necessary.

For a more in-depth getting started guide, visit the
[Getting Started](https://fresh.deno.dev/docs/getting-started) page in the Fresh
docs.

## Contributing

We appreciate your help! To contribute, please read our
[contributing guideline](./.github/CONTRIBUTING.md).

## Adding your project to the showcase

If you feel that your project would be helpful to other Fresh users, please
consider putting your project on the
[showcase](https://fresh.deno.dev/showcase). However, websites that are just for
promotional purposes may not be listed.

To take a screenshot, run the following command.

```sh
deno task screenshot [url] [your-app-name]
```

Then add your site to
[showcase.json](https://github.com/denoland/fresh/blob/main/www/data/showcase.json),
preferably with source code on GitHub, but not required.

## Badges

![Made with Fresh](./www/static/fresh-badge.svg)

```md
[![Made with Fresh](https://fresh.deno.dev/fresh-badge.svg)](https://fresh.deno.dev)
```

```html
<a href="https://fresh.deno.dev">
  <img
    width="197"
    height="37"
    src="https://fresh.deno.dev/fresh-badge.svg"
    alt="Made with Fresh"
  />
</a>
```

![Made with Fresh(dark)](./www/static/fresh-badge-dark.svg)

```md
[![Made with Fresh](https://fresh.deno.dev/fresh-badge-dark.svg)](https://fresh.deno.dev)
```

```html
<a href="https://fresh.deno.dev">
  <img
    width="197"
    height="37"
    src="https://fresh.deno.dev/fresh-badge-dark.svg"
    alt="Made with Fresh"
  />
</a>
```

## Hashtags

Use the following hashtags in your social media posts that reference Fresh and
as Topics in the About section of your GitHub repos that contain Fresh code. It
will assure maximum visibility for your posts and code, and promote Fresh
development ecosystem visibility.

- #denofresh
- #deno

Github repo Topics will not include the hash symbol.


================================================
FILE: _typos.toml
================================================
[files]
extend-exclude = [
  "packages/fresh/tests/fixture_partials/routes/scroll_restoration/index.tsx",
  "www/static/fonts/FixelVariable.woff2",
  "www/static/fonts/FixelVariableItalic.woff2",
  "packages/fresh/tests/lorem_ipsum.txt",
]

[default]
extend-ignore-identifiers-re = ["Fixel"]


================================================
FILE: deno.json
================================================
{
  "vendor": true,
  "nodeModulesDir": "manual",
  "workspace": [
    "./packages/*",
    "./www"
  ],
  "tasks": {
    "demo": "deno task --cwd=packages/plugin-vite demo",
    "demo:build": "deno task --cwd=packages/plugin-vite demo:build",
    "demo:start": "deno task --cwd=packages/plugin-vite demo:start",
    "test": "deno test -A --parallel",
    "www": "deno task --cwd=www dev",
    "build-www": "deno task --cwd=www build",
    "screenshot": "deno run -A www/utils/screenshot.ts",
    "check:types": "deno check --allow-import",
    "check:docs": "deno run -A tools/check_docs.ts",
    "ok": "deno fmt --check && deno lint && deno task check:types && deno task test",
    "test:www": "deno test -A www/main_test.*",
    "release": "deno run -A tools/release.ts"
  },
  "exclude": [
    "**/_fresh/*",
    "**/tmp/*",
    "*/tests_OLD/**",
    "**/vite.config.ts.*",
    "*/vite.config.ts.*",
    "vite.config.ts.*"
  ],
  "publish": {
    "include": [
      "src/**",
      "deno.json",
      "README.md",
      "LICENSE",
      "www/static/fresh-badge.svg",
      "www/static/fresh-badge-dark.svg",
      "*.todo"
    ],
    "exclude": ["**/*_test.*", "src/__OLD/**", "*.todo", "**/tests/**"]
  },
  "imports": {
    "@deno/doc": "jsr:@deno/doc@^0.172.0",
    "@deno/esbuild-plugin": "jsr:@deno/esbuild-plugin@^1.2.0",
    "@fresh/build-id": "jsr:@fresh/build-id@^1.0.0",
    "@std/cli": "jsr:@std/cli@^1.0.19",
    "@std/collections": "jsr:@std/collections@^1.1.2",
    "@std/dotenv": "jsr:@std/dotenv@^0.225.5",
    "@std/http": "jsr:@std/http@^1.0.15",
    "@std/uuid": "jsr:@std/uuid@^1.0.7",
    "@supabase/postgrest-js": "npm:@supabase/postgrest-js@^1.21.4",
    "@types/mime-db": "npm:@types/mime-db@^1.43.6",
    "@types/node": "npm:@types/node@^24.3.0",
    "@types/pg": "npm:@types/pg@^8.15.5",
    "@types/prismjs": "npm:@types/prismjs@^1.26.5",
    "docsearch": "https://esm.sh/@docsearch/js@3.5.2?target=es2020",
    "esbuild": "npm:esbuild@0.25.7",
    "esbuild-wasm": "npm:esbuild-wasm@0.25.7",
    "fresh": "jsr:@fresh/core@^2.0.0",
    "mime-db": "npm:mime-db@^1.54.0",
    "preact": "npm:preact@^10.28.2",
    "preact-render-to-string": "npm:preact-render-to-string@^6.6.5",
    "$ga4": "https://raw.githubusercontent.com/denoland/ga4/main/mod.ts",
    "@opentelemetry/api": "npm:@opentelemetry/api@^1.9.0",
    "@preact/signals": "npm:@preact/signals@^2.5.1",
    "@std/encoding": "jsr:@std/encoding@1",
    "@std/fmt": "jsr:@std/fmt@^1.0.7",
    "@std/fs": "jsr:@std/fs@1",
    "@std/html": "jsr:@std/html@1",
    "@std/jsonc": "jsr:@std/jsonc@1",
    "@std/media-types": "jsr:@std/media-types@1",
    "@std/path": "jsr:@std/path@1",
    "@std/semver": "jsr:@std/semver@1",
    "@std/streams": "jsr:@std/streams@1",

    "@astral/astral": "jsr:@astral/astral@^0.5.5",
    "@marvinh-test/fresh-island": "jsr:@marvinh-test/fresh-island@^0.0.3",
    "linkedom": "npm:linkedom@^0.18.10",
    "@std/async": "jsr:@std/async@^1.0.13",
    "@std/expect": "jsr:@std/expect@^1.0.16",
    "@std/testing": "jsr:@std/testing@^1.0.12",

    "@tailwindcss/postcss": "npm:@tailwindcss/postcss@^4.1.10",
    "redis": "npm:redis@^5.8.2",
    "rollup": "npm:rollup@^4.55.1",
    "tailwindcss": "npm:tailwindcss@^4.1.10",
    "postcss": "npm:postcss@8.5.6",

    "ts-morph": "npm:ts-morph@^26.0.0",

    "@std/front-matter": "jsr:@std/front-matter@^1.0.5",
    "github-slugger": "npm:github-slugger@^2.0.0",
    "imagescript": "https://deno.land/x/imagescript@1.3.0/mod.ts",
    "marked": "npm:marked@^15.0.11",
    "marked-mangle": "npm:marked-mangle@^1.1.9",
    "prismjs": "npm:prismjs@^1.29.0",
    "vite": "npm:vite@^7.3.1"
  },
  "compilerOptions": {
    "lib": ["dom", "dom.asynciterable", "deno.ns", "deno.unstable"],
    "jsx": "precompile",
    "jsxImportSource": "preact",
    "jsxPrecompileSkipElements": [
      "a",
      "img",
      "source",
      "body",
      "html",
      "head",
      "title",
      "meta",
      "script",
      "link",
      "style",
      "base",
      "noscript",
      "template"
    ],
    "types": ["vite/client"]
  },
  "lint": {
    "rules": {
      "tags": ["recommended", "fresh", "jsr", "jsx", "react"],
      "exclude": ["no-window"],
      "include": ["no-console"]
    }
  },
  "fmt": {
    "exclude": ["./www/static/**/*.svg"]
  }
}


================================================
FILE: docs/1.x/concepts/ahead-of-time-builds.md
================================================
---
description: |
  Fresh optimize assets ahead of time, which makes pages load way quicker.
---

Fresh enables you to pre-optimize frontend assets before the code is deployed.
During that process the code for Islands will be compressed and optimized, so
that Fresh can send as little code as possible to the browser. Depending on the
amount of code an island needs, this process can take several seconds if done on
the fly server-side.

Doing those optimizations ahead-of-time and deploying the already optimized
assets alongside with your code, allows Fresh to treat them as like any other
static file and can serve it immediately without any further processing. On
pages with islands, having to do no processing greatly speeds up page load
times.

Plugins can build static assets during ahead-of-time builds. This can be used to
pre-process or generate CSS files, for example.

## Creating an optimized build

To have Fresh optimize all the assets, run one of the following commands:

```sh Terminal
# As a task in newer Fresh projects
deno task build
# or invoke it manually
deno run -A dev.ts build
```

This will create a `_fresh` folder in the project directory. That folder
contains the optimized assets and a `snapshot.json` file which includes some
metadata for Fresh.

Any other static files generated by plugins will be stored in the
`_fresh/static` subfolder. They will be served the same as other
[static files](/docs/1.x/concepts/static-files.md).

> [info]: The `_fresh` folder should not be committed to the repository. Add an
> entry in the `.gitignore` file to ensure that it is not committed. Create that
> file at the root of your git repository if not present.
>
> ```gitignore .gitignore
> # Ignore fresh build directory
> _fresh/
> ```

## Running Fresh with optimized assets

When Fresh is started in non-development mode (usually via `main.ts`), Fresh
will automatically pick up optimized assets when a `_fresh` folder exists. If
found, Fresh will print the following message to the terminal:

```sh Terminal output
Using snapshot found at /path/to/project/_fresh
```

## Deploying an optimized Fresh project

If you are deploying a Fresh project to Deno Deploy, you can use ahead-of-time
builds to optimize the assets before deploying them. This will make your
application load quicker.

Open the Deno Deploy dashboard for your project and head to the "Git
Integration" section in the project settings. Enter `deno task build` in the
"Build command" field and save. This will switch your Deno Deploy project to use
ahead-of-time builds.

## Migrating existing projects with Plugins

If you're using Fresh plugins, extract them into a `fresh.config.ts` file, so
that both the `dev.ts` and `main.ts` script have access to them.

```ts fresh.config.ts
import { defineConfig } from "$fresh/server.ts";
import twindPlugin from "$fresh/plugins/twind.ts";
import twindConfig from "./twind.config.ts";

export default defineConfig({
  plugins: [twindPlugin(twindConfig)],
});
```

```ts main.ts
import { start } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";
import config from "./fresh.config.ts";

await start(manifest, config);
```

```ts dev.ts
import dev from "$fresh/dev.ts";
import config from "./fresh.config.ts";

await dev(import.meta.url, "./main.ts", config);
```


================================================
FILE: docs/1.x/concepts/app-wrapper.md
================================================
---
description: |
  Add a global app wrapper to provide common meta tags or context for application routes.
---

An app wrapper is defined in an `_app.tsx` file in `routes/` folder and is
typically used to create the outer structure of an HTML document. It must
contain a default export that is a regular Preact component. Only one such
wrapper is allowed per application.

The component to be wrapped is received via props, in addition to a few other
things. This allows for the introduction of a global container functioning as a
template which can be conditioned based on state and params. Note that any state
set by middleware is available via `props.state`.

```tsx routes/_app.tsx
import { PageProps } from "$fresh/server.ts";

export default function App({ Component, state }: PageProps) {
  // do something with state here
  return (
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>My Fresh app</title>
      </head>
      <body>
        <Component />
      </body>
    </html>
  );
}
```

## Async app wrapper

Similar to routes and layouts, the app wrapper can be made asynchronous. This
changes the function signature so that the first argument is the `Request`
instance and the second one is the `FreshContext`.

```tsx routes/_app.tsx
import { FreshContext } from "$fresh/server.ts";

export default async function App(req: Request, ctx: FreshContext) {
  const data = await loadData();

  return (
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>My Fresh app</title>
      </head>
      <body>
        <h1>Hello {data.name}</h1>
        <ctx.Component />
      </body>
    </html>
  );
}
```

### Define helper

To make it quicker to type the async app wrapper, Fresh includes a `defineApp`
helper which already infers the correct types for you.

```tsx routes/_app.tsx
import { defineApp } from "$fresh/server.ts";

export default defineApp(async (req, ctx) => {
  const data = await loadData();

  return (
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>My Fresh app</title>
      </head>
      <body>
        <h1>Hello {data.name}</h1>
        <ctx.Component />
      </body>
    </html>
  );
});
```

## Disabling the app wrapper

Rendering the app wrapper can be skipped on a route or layout basis. To do that,
set `skipAppWrapper: true` to the layout or route config.

```tsx routes/my-special-route.tsx
import { RouteConfig } from "$fresh/server.ts";

export const config: RouteConfig = {
  skipAppWrapper: true, // Skip the app wrapper during rendering
};

export default function Page() {
  // ...
}
```


================================================
FILE: docs/1.x/concepts/architecture.md
================================================
---
description: |
  Fresh's architecture is designed to make it easy to build fast, scalable, and reliable applications.
---

Fresh is designed to make it easy to build fast, scalable, and reliable
applications. To do this, it makes opinionated decisions about how one should
build web applications. These decisions are backed by strong empirical data
gathered from experts in the field. Some examples of these principles are:

- Page load times should be reduced to a minimum.
- The work performed on the client should be minimized.
- Errors should have a small blast radius - stuff should gracefully degrade.

The single biggest architecture decision that Fresh makes is its usage of the
[islands architecture][islands] pattern. This means that Fresh applications ship
pure HTML to the client by default. Parts of a server-rendered page can then be
independently re-hydrated with interactive widgets (islands). This means that
the client is only responsible for rendering parts of the page that are
interactive enough to warrant the extra effort. Any content that is purely
static does not have related client-side JavaScript and is thus very
lightweight.

<!-- TODO(lucacasonato): elaborate on request handling, form actions, etc. -->

[islands]: https://www.patterns.dev/posts/islands-architecture/


================================================
FILE: docs/1.x/concepts/data-fetching.md
================================================
---
description: |
  Data fetching in Fresh happens inside of route handler functions. These can pass route data to the page via page props.
---

Server side data fetching in Fresh is accomplished through asynchronous handler
functions. These handler functions can call a `ctx.render()` function with the
data to be rendered as an argument. This data can then be retrieved by the page
component through the `data` property on the `props`.

Here is an example:

```tsx routes/projects/[id].tsx
interface Project {
  name: string;
  stars: number;
}

export const handler: Handlers<Project> = {
  async GET(_req, ctx) {
    const project = await db.projects.findOne({ id: ctx.params.id });
    if (!project) {
      return ctx.renderNotFound({
        message: "Project does not exist",
      });
    }
    return ctx.render(project);
  },
};

export default function ProjectPage(props: PageProps<Project>) {
  return (
    <div>
      <h1>{props.data.name}</h1>
      <p>{props.data.stars} stars</p>
    </div>
  );
}
```

The type parameter on the `PageProps`, `Handlers`, `Handler`, and `FreshContext`
can be used to enforce a TypeScript type to use for the render data. Fresh
enforces during type checking that the types in all of these fields are
compatible within a single page.

## Asynchronous routes

As a shortcut for combining a `GET` handler with a route, you can define your
route as `async`. An `async` route (a route that returns a promise) will be
called with the `Request` and a `RouteContext` (similar to a `HandlerContext`).
Here is the above example rewritten using this shortcut:

```tsx routes/projects/[id].tsx
interface Project {
  name: string;
  stars: number;
}

export default async function ProjectPage(_req, ctx: FreshContext) {
  const project: Project | null = await db.projects.findOne({
    id: ctx.params.id,
  });

  if (!project) {
    return <h1>Project not found</h1>;
  }

  return (
    <div>
      <h1>{project.name}</h1>
      <p>{project.stars} stars</p>
    </div>
  );
}
```


================================================
FILE: docs/1.x/concepts/deployment.md
================================================
---
description: |
  Fresh can be deployed to a variety of platforms easily.
---

While Fresh is designed to be deployed to [Deno Deploy][deno-deploy], it can be
deployed to any system or platform that can run a Deno based web server.

Here are instructions for specific providers / systems:

- [Deno Deploy](#deno-deploy)
- [Docker](#docker)
- [Self Contained Executable](#self-contained-executable)

## Deno Deploy

The recommended way to deploy Fresh is by using Deno Deploy. Deno Deploy
provides a GitHub integration that can deploy your Fresh projects to its
globally distributed edge network in seconds, automatically.

View [the getting started guide][deploy-to-production] for instructions on how
to deploy Fresh to Deno Deploy.

## Docker

You can deploy Fresh to any platform that can run Docker containers. Docker is a
tool to containerize projects and portably run them on any supported platform.

When packaging your Fresh app for Docker, it is important that you set the
`DENO_DEPLOYMENT_ID` environment variable in your container. This variable needs
to be set to an opaque string ID that represents the version of your application
that is currently being run. This could be a Git commit hash, or a hash of all
files in your project. It is critical for the function of Fresh that this ID
changes when _any_ file in your project changes - if it doesn't, incorrect
caching **will** cause your project to not function correctly.

Here is an example `Dockerfile` for a Fresh project:

```dockerfile Dockerfile
FROM denoland/deno:1.38.3

ARG GIT_REVISION
ENV DENO_DEPLOYMENT_ID=${GIT_REVISION}

WORKDIR /app

COPY . .
RUN deno cache main.ts

EXPOSE 8000

CMD ["run", "-A", "main.ts"]
```

To build your Docker image inside of a Git repository:

```sh Terminal
$ docker build --build-arg GIT_REVISION=$(git rev-parse HEAD) -t my-fresh-app .
```

Then run your Docker container:

```sh Terminal
$ docker run -t -i -p 80:8000 my-fresh-app
```

To deploy to a cloud provider, push it to a container registry and follow their
documentation.

- [Amazon Web Services][aws-container-registry]
- [Google Cloud][gcp-container-registry]

## Self Contained Executable

With Deno 2.1, you can create a self-contained executable of your Fresh project
that includes all assets and dependencies. This executable can run on any
platform without requiring Deno to be installed.

```sh Terminal
$ deno task build
$ deno compile --include static --include _fresh --include deno.json -A main.ts
```

[aws-container-registry]: https://docs.aws.amazon.com/AmazonECS/latest/userguide/create-container-image.html#create-container-image-push-ecr
[gcp-container-registry]: https://cloud.google.com/container-registry/docs/pushing-and-pulling
[deno-deploy]: https://deno.com/deploy
[deploy-to-production]: /docs/1.x/getting-started/deploy-to-production


================================================
FILE: docs/1.x/concepts/error-pages.md
================================================
---
description: |
  Error pages can be used to customize the page that is shown when an error occurs in the application.
---

Fresh supports customizing the `404 Not Found`, and the
`500 Internal Server Error` pages. These are shown when a request is made but no
matching route exists, and when a middleware, route handler, or page component
throws an error respectively.

### 404: Not Found

The 404 page can be customized by creating a `_404.tsx` file in the `routes/`
folder. The file must have a default export that is a regular Preact component.
A props object of type `PageProps` is passed in as an argument.

```tsx routes/_404.tsx
import { PageProps } from "$fresh/server.ts";

export default function NotFoundPage({ url }: PageProps) {
  return <p>404 not found: {url.pathname}</p>;
}
```

#### Manually render 404 pages

The `_404.tsx` file will be invoked automatically when no route matches the URL.
In some cases, one needs to manually trigger the rendering of the 404 page, for
example when the route did match, but the requested resource does not exist.
This can be achieved with `ctx.renderNotFound`.

```tsx routes/blog/[slug].tsx
import { Handlers, PageProps } from "$fresh/server.ts";

export const handler: Handlers = {
  async GET(req, ctx) {
    const blogpost = await fetchBlogpost(ctx.params.slug);
    if (!blogpost) {
      return ctx.renderNotFound({
        custom: "prop",
      });
    }
    return ctx.render({ blogpost });
  },
};

export default function BlogpostPage({ data }) {
  return (
    <article>
      <h1>{data.blogpost.title}</h1>
      {/* rest of your page */}
    </article>
  );
}
```

This can also be achieved by throwing an error, if you're uninterested in
passing specific data to your 404 page:

```tsx routes/missing-page.tsx
import { Handlers } from "$fresh/server.ts";

export const handler: Handlers = {
  GET(_req, _ctx) {
    throw new Deno.errors.NotFound();
  },
};
```

### 500: Internal Server Error

The 500 page can be customized by creating a `_500.tsx` file in the `routes/`
folder. The file must have a default export that is a regular Preact component.
A props object of type `PageProps` is passed in as an argument.

```tsx routes/_500.tsx
import { PageProps } from "$fresh/server.ts";

export default function Error500Page({ error }: PageProps) {
  return <p>500 internal error: {(error as Error).message}</p>;
}
```


================================================
FILE: docs/1.x/concepts/forms.md
================================================
---
description: |
  Robustly handle user inputs using HTML `<form>` elements client side, and form
  submission handlers server side.
---

For stronger resiliency and user experience, Fresh relies on native browser
support for form submissions with the HTML `<form>` element.

In the browser, a `<form>` submit will send an HTML action (usually `GET` or
`POST`) to the server, which responds with a new page to render.

## POST request with `application/x-www-form-urlencoded`

Forms typically submit as a `GET` request with data encoded in the URL's search
parameters, or as a `POST` request with either an
`application/x-www-form-urlencoded` or `multipart/form-data` body.

This example demonstrates how to handle `application/x-www-form-urlencoded`
`<form>` submissions:

```tsx routes/subscribe.tsx
import { Handlers } from "$fresh/server.ts";

export const handler: Handlers = {
  async GET(req, ctx) {
    return await ctx.render();
  },
  async POST(req, ctx) {
    const form = await req.formData();
    const email = form.get("email")?.toString();

    // Add email to list.

    // Redirect user to thank you page.
    const headers = new Headers();
    headers.set("location", "/thanks-for-subscribing");
    return new Response(null, {
      status: 303, // See Other
      headers,
    });
  },
};

export default function Subscribe() {
  return (
    <>
      <form method="post">
        <input type="email" name="email" value="" />
        <button type="submit">Subscribe</button>
      </form>
    </>
  );
}
```

When the user submits the form, Deno will retrieve the `email` value using the
request's `formData()` method, add the email to a list, and redirect the user to
a thank you page.

## Handling file uploads

File uploads can be handled in a very similar manner to the example above. Note
that this time, we have to explicitly declare the form's encoding to be
`multipart/form-data`.

```tsx routes/subscribe.tsx
import { Handlers, type PageProps } from "$fresh/server.ts";

interface Props {
  message: string | null;
}

export const handler: Handlers<Props> = {
  async GET(req, ctx) {
    return await ctx.render({
      message: null,
    });
  },
  async POST(req, ctx) {
    const form = await req.formData();
    const file = form.get("my-file") as File;

    if (!file) {
      return ctx.render({
        message: `Please try again`,
      });
    }

    const name = file.name;
    const contents = await file.text();

    console.log(contents);

    return ctx.render({
      message: `${name} uploaded!`,
    });
  },
};

export default function Upload(props: PageProps<Props>) {
  const { message } = props.data;
  return (
    <>
      <form method="post" encType="multipart/form-data">
        <input type="file" name="my-file" />
        <button type="submit">Upload</button>
      </form>
      {message ? <p>{message}</p> : null}
    </>
  );
}
```

## A note of caution

These examples are simplified to demonstrate how Deno and Fresh handle HTTP
requests. In the Real World™, you'll want to validate your data (_especially the
file type_) and protect against cross-site request forgery. Consider yourself
warned.


================================================
FILE: docs/1.x/concepts/index.md
================================================
---
description: |
  This chapter goes over some fundamental concepts of Fresh.
---

This chapter goes over some fundamental concepts of Fresh. It covers the
overarching architecture design of Fresh applications, as well as reference
documentation about the various features of Fresh.


================================================
FILE: docs/1.x/concepts/islands.md
================================================
---
description: |
  Islands enable client side interactivity in Fresh. They are hydrated on the client in addition to being rendered on the server.
---

Islands enable client side interactivity in Fresh. Islands are isolated Preact
components that are rendered on the server and then hydrated on the client. This
is different from all other components in Fresh, as they are usually rendered on
the server only.

Islands are defined by creating a file in the `islands/` folder in a Fresh
project. The name of this file must be a PascalCase or kebab-case name of the
island.

```tsx islands/my-island.tsx
import { useSignal } from "@preact/signals";

export default function MyIsland() {
  const count = useSignal(0);

  return (
    <div>
      Counter is at {count}.{" "}
      <button onClick={() => (count.value += 1)}>+</button>
    </div>
  );
}
```

An island can be used in a page like a regular Preact component. Fresh will take
care of automatically re-hydrating the island on the client.

```tsx route/index.tsx
import MyIsland from "../islands/my-island.tsx";

export default function Home() {
  return <MyIsland />;
}
```

## Passing JSX to islands

Islands support passing JSX elements via the `children` property.

```tsx islands/my-island.tsx
import { useSignal } from "@preact/signals";
import { ComponentChildren } from "preact";

interface Props {
  children: ComponentChildren;
}

export default function MyIsland({ children }: Props) {
  const count = useSignal(0);

  return (
    <div>
      Counter is at {count}.{" "}
      <button onClick={() => (count.value += 1)}>+</button>
      {children}
    </div>
  );
}
```

This allows you to pass static content rendered by the server to an island in
the browser.

```tsx routes/index.tsx
import MyIsland from "../islands/my-island.tsx";

export default function Home() {
  return (
    <MyIsland>
      <p>This text is rendered on the server</p>
    </MyIsland>
  );
}
```

You can also create shared components in your `components/` directory, which can
be used in both static content and interactive islands. When these components
are used within islands, interactivity can be added, such as `onClick` handlers
(using an `onClick` handler on a button outside of an island will not fire).

```tsx islands/my-island.tsx
import { useSignal } from "@preact/signals";
import { ComponentChildren } from "preact";
import Card from "../components/Card.tsx";
import Button from "../components/Button.tsx";

interface Props {
  children: ComponentChildren;
}

export default function MyIsland({ children }: Props) {
  const count = useSignal(0);

  return (
    <Card>
      Counter is at {count}.{" "}
      <Button onClick={() => (count.value += 1)}>+</Button>
      {children}
    </Card>
  );
}
```

## Passing other props to islands

Passing props to islands is supported, but only if the props are serializable.
Fresh can serialize the following types of values:

- Primitive types `string`, `boolean`, `bigint`, and `null`
- Most `number`s (`Infinity`, `-Infinity`, and `NaN` are silently converted to
  `null`)
- Plain objects with string keys and serializable values
- Arrays containing serializable values
- Uint8Array
- JSX Elements (restricted to `props.children`)
- Preact Signals (if the inner value is serializable)

Circular references are supported. If an object or signal is referenced multiple
times, it is only serialized once and the references are restored upon
deserialization. Passing complex objects like `Date`, custom classes, or
functions is not supported.

During server side rendering, Fresh annotates the HTML with special comments
that indicate where each island will go. This gives the code sent to the client
enough information to put the islands where they are supposed to go without
requiring hydration for the static children of interactive islands. No
Javascript is sent to the client when no interactivity is needed.

```html Response body
<!--frsh-myisland_default:default:0-->
<div>
  Counter is at 0.
  <button>+</button>
  <!--frsh-slot-myisland_default:children-->
  <p>This text is rendered on the server</p>
  <!--/frsh-slot-myisland_default:children-->
</div>
<!--/frsh-myisland_default:default:0-->
```

### Nesting islands

Islands can be nested within other islands as well. In that scenario they act
like a normal Preact component, but still receive the serialized props if any
were present.

```tsx islands/other-island.tsx
import { useSignal } from "@preact/signals";
import { ComponentChildren } from "preact";

interface Props {
  children: ComponentChildren;
  foo: string;
}

function randomNumber() {
  return Math.floor(Math.random() * 100);
}

export default function OtherIsland({ children, foo }: Props) {
  const number = useSignal(randomNumber());

  return (
    <div>
      <p>String from props: {foo}</p>
      <p>
        <button onClick={() => (number.value = randomNumber())}>Random</button>
        {" "}
        number is: {number}.
      </p>
    </div>
  );
}
```

In essence, Fresh allows you to mix static and interactive parts in your app in
a way that's most optimal for your app. We'll keep sending only the JavaScript
that is needed for the islands to the browser.

```tsx route/index.tsx
import MyIsland from "../islands/my-island.tsx";
import OtherIsland from "../islands/other-island.tsx";

export default function Home() {
  return (
    <div>
      <MyIsland>
        <OtherIsland foo="this prop will be serialized" />
      </MyIsland>
      <p>Some more server rendered text</p>
    </div>
  );
}
```

## Rendering islands on client only

When using client-only APIs, like `EventSource` or `navigator.getUserMedia`,
this component will not run on the server as it will produce an error like:

```
An error occurred during route handling or page rendering. ReferenceError: EventSource is not defined
    at Object.MyIsland (file:///Users/someuser/fresh-project/islandsmy-island.tsx:6:18)
    at m (https://esm.sh/v129/preact-render-to-string@6.2.0/X-ZS8q/denonext/preact-render-to-string.mjs:2:2602)
    at m (https://esm.sh/v129/preact-render-to-string@6.2.0/X-ZS8q/denonext/preact-render-to-string.mjs:2:2113)
    ....
```

Use the [`IS_BROWSER`](https://deno.land/x/fresh/runtime.ts?doc=&s=IS_BROWSER)
flag as a guard to fix the issue:

```tsx islands/my-island.tsx
import { IS_BROWSER } from "$fresh/runtime.ts";

export function MyIsland() {
  // Return any prerenderable JSX here which makes sense for your island
  if (!IS_BROWSER) return <div></div>;

  // All the code which must run in the browser comes here!
  // Like: EventSource, navigator.getUserMedia, etc.
  return <div></div>;
}
```


================================================
FILE: docs/1.x/concepts/layouts.md
================================================
---
description: |
  Add a layout to provide common meta tags, context for application sub routes, and common layout.
---

A layout is defined in a `_layout.tsx` file in any sub directory (at any level)
under the `routes/` folder. It must contain a default export that is a regular
Preact component. Only one such layout is allowed per sub directory.

```txt-files Project structure
<project root>
└── routes
    ├── sub
    │   ├── page.tsx
    │   └── index.tsx
    ├── other
    │   ├── _layout.tsx  # will be applied on top of `routes/_layout.tsx`
    │   └── page.tsx
    ├── _layout.tsx  # will be applied to all routes
    └── _app.tsx
```

The component to be wrapped is received via props, in addition to a few other
things. This allows for the introduction of a global container functioning as a
template which can be conditioned based on state and params. Note that any state
set by middleware is available via `props.state`.

```tsx routes/sub/_layout.tsx
import { PageProps } from "$fresh/server.ts";

export default function Layout({ Component, state }: PageProps) {
  // do something with state here
  return (
    <div class="layout">
      <Component />
    </div>
  );
}
```

## Async layouts

In case you need to fetch data asynchronously before rendering the layout, you
can use an async layout to do so.

```tsx routes/sub/_layout.tsx
import { FreshContext } from "$fresh/server.ts";

export default async function Layout(req: Request, ctx: FreshContext) {
  // do something with state here
  const data = await loadData();

  return (
    <div class="layout">
      <p>{data.greeting}</p>
      <ctx.Component />
    </div>
  );
}
```

### Define helper

To make it a little quicker to write async layouts, Fresh ships with a
`defineLayout` helper which automatically infers the correct types for the
function arguments.

```tsx routes/greet/_layout.tsx
import { defineLayout } from "$fresh/server.ts";

export default defineLayout(async (req, ctx) => {
  const data = await loadData();

  return (
    <div class="layout">
      <p>{data.greeting}</p>
      <ctx.Component />
    </div>
  );
});
```

## Opting out of layout inheritance

Sometimes you want to opt out of the layout inheritance mechanism for a
particular route. This can be done via route configuration. Picture a directory
structure like this:

```txt-files Project structure
└── <root>/routes
    ├── sub
    │   ├── _layout_.tsx
    │   ├── special.tsx  # should not inherit layouts
    │   └── index.tsx
    └── _layout.tsx
```

To make `routes/sub/special.tsx` opt out of rendering layouts we can set
`skipInheritedLayouts: true`.

```tsx routes/sub/special.tsx
import { RouteConfig } from "$fresh/server.ts";

export const config: RouteConfig = {
  skipInheritedLayouts: true, // Skip already inherited layouts
};

export default function MyPage() {
  return <p>Hello world</p>;
}
```

You can skip already inherited layouts inside a layout file:

```tsx routes/special/_layout.tsx
import { LayoutConfig } from "$fresh/server.ts";

export const config: LayoutConfig = {
  skipInheritedLayouts: true, // Skip already inherited layouts
};

export default function MyPage() {
  return <p>Hello world</p>;
}
```


================================================
FILE: docs/1.x/concepts/middleware.md
================================================
---
description: |
  Add middleware routes to intercept requests or responses for analytics purposes, access control, or anything else.
---

A middleware is defined in a `_middleware.ts` file. It will intercept the
request in order for you to perform custom logic before or after the route
handler. This allows modifying or checking requests and responses. Common
use-cases for this are logging, authentication, and performance monitoring.

Each middleware gets passed a `next` function in the context argument that is
used to trigger child handlers. The `ctx` also has a `state` property that can
be used to pass arbitrary data to downstream (or upstream) handlers. This
`state` is included in `PageProps` by default, which is available to both the
special [\_app](/docs/1.x/concepts/app-wrapper.md) wrapper and normal
[routes](/docs/1.x/concepts/routes.md). `ctx.state` is normally set by modifying
its properties, e.g. `ctx.state.loggedIn = true`, but you can also replace the
entire object like `ctx.state = { loggedIn: true }`.

```ts routes/_middleware.ts
import { FreshContext } from "$fresh/server.ts";

interface State {
  data: string;
}

export async function handler(
  req: Request,
  ctx: FreshContext<State>,
) {
  ctx.state.data = "myData";
  const resp = await ctx.next();
  resp.headers.set("server", "fresh server");
  return resp;
}
```

```ts routes/myHandler.ts
export const handler: Handlers<any, { data: string }> = {
  GET(_req, ctx) {
    return new Response(`middleware data is ${ctx.state.data}`);
  },
};
```

Middlewares are scoped and can be layered. This means a project can have
multiple middlewares, each covering a different set of routes. If multiple
middlewares cover a route, they will all be run, in order of specificity (least
specific first).

For example, take a project with the following routes:

```txt-files Project Structure
└── <root>/routes
    ├── _middleware.ts
    ├── index.ts
    └── admin
        ├── _middleware.ts
        └── index.ts
        └── signin.ts
```

For a request to `/` the request will flow like this:

1. The `routes/_middleware.ts` middleware is invoked.
2. Calling `ctx.next()` will invoke the `routes/index.ts` handler.

For a request to `/admin` the request flows like this:

1. The `routes/_middleware.ts` middleware is invoked.
2. Calling `ctx.next()` will invoke the `routes/admin/_middleware.ts`
   middleware.
3. Calling `ctx.next()` will invoke the `routes/admin/index.ts` handler.

For a request to `/admin/signin` the request flows like this:

1. The `routes/_middleware.ts` middleware is invoked.
2. Calling `ctx.next()` will invoke the `routes/admin/_middleware.ts`
   middleware.
3. Calling `ctx.next()` will invoke the `routes/admin/signin.ts` handler.

A single middleware file can also define multiple middlewares (all for the same
route) by exporting an array of handlers instead of a single handler. For
example:

```ts routes/_middleware.ts
export const handler = [
  async function middleware1(req, ctx) {
    // do something
    return ctx.next();
  },
  async function middleware2(req, ctx) {
    // do something
    return ctx.next();
  },
];
```

It should be noted that `middleware` has access to route parameters. If you're
running a fictitious `routes/[tenant]/admin/_middleware.ts` like this:

```ts routes/[tenant]/admin/_middleware.ts
import { FreshContext } from "$fresh/server.ts";

export async function handler(_req: Request, ctx: FreshContext) {
  const currentTenant = ctx.params.tenant;
  // do something with the tenant
  const resp = await ctx.next();
  return resp;
}
```

and the request is to `mysaas.com/acme/admin/`, then `currentTenant` will have
the value of `acme` in your middleware.

## Middleware Destination

To set the stage for this section, let's focus on the part of `FreshContext`
that looks like this:

```ts fresh 🍋
export interface FreshContext<State = Record<string, unknown>> {
  ...
  next: () => Promise<Response>;
  state: State;
  destination: router.DestinationKind;
  remoteAddr: {
    transport: "tcp" | "udp";
    hostname: string;
    port: number;
  };
  ...
}
```

and `router.DestinationKind` is defined like this:

```ts fresh 🍋
export type DestinationKind = "internal" | "static" | "route" | "notFound";
```

This is useful if you want your middleware to only run when a request is headed
for a `route`, as opposed to something like `http://localhost:8001/favicon.ico`.

### Example

Initiate a new Fresh project (`deno run -A -r https://fresh.deno.dev/`) and then
create a `_middleware.ts` file in the `routes` folder like this:

```ts routes/_middleware.ts
import { FreshContext } from "$fresh/server.ts";

export async function handler(req: Request, ctx: FreshContext) {
  console.log(ctx.destination);
  console.log(req.url);
  const resp = await ctx.next();
  return resp;
}
```

If you start up your server (`deno task start`) you'll see the following:

```sh Terminal
Task start deno run -A --watch=static/,routes/ dev.ts
Watcher Process started.
The manifest has been generated for 4 routes and 1 islands.

 🍋 Fresh ready
    Local: http://localhost:8000/

route
http://localhost:8000/
internal
http://localhost:8000/_frsh/js/3c7400558fc00915df88cb181036c0dbf73ab7f5/deserializer.js
internal
http://localhost:8000/_frsh/js/3c7400558fc00915df88cb181036c0dbf73ab7f5/signals.js
internal
http://localhost:8000/_frsh/js/3c7400558fc00915df88cb181036c0dbf73ab7f5/plugin-twind-main.js
internal
http://localhost:8000/_frsh/js/3c7400558fc00915df88cb181036c0dbf73ab7f5/main.js
internal
http://localhost:8000/_frsh/js/3c7400558fc00915df88cb181036c0dbf73ab7f5/island-counter.js
internal
http://localhost:8000/_frsh/refresh.js
static
http://localhost:8000/logo.svg?__frsh_c=3c7400558fc00915df88cb181036c0dbf73ab7f5
internal
http://localhost:8000/_frsh/alive
internal
http://localhost:8000/_frsh/js/3c7400558fc00915df88cb181036c0dbf73ab7f5/chunk-PDMKJVJ5.js
internal
http://localhost:8000/_frsh/js/3c7400558fc00915df88cb181036c0dbf73ab7f5/chunk-UGFDDSOV.js
internal
http://localhost:8000/_frsh/js/3c7400558fc00915df88cb181036c0dbf73ab7f5/chunk-RCK7U3UF.js
```

That first `route` request is for when `Fresh` responds with the root level
`index.tsx` route. The rest, as you can see, are either `internal` or `static`
requests. You can use `ctx.destination` to filter these out if your middleware
is only supposed to deal with routes.

## Middleware Redirects

If you want to redirect a request from a middleware, you can do so by returning:

```ts routes/_middleware.ts
export function handler(req: Request): Response {
  return Response.redirect("https://example.com", 307);
}
```

`307` stands for temporary redirect. You can also use `301` for permanent
redirect. You can also redirect to a relative path by doing:

```ts routes/_middleware.ts
export function handler(req: Request): Response {
  return new Response("", {
    status: 307,
    headers: { Location: "/my/new/relative/path" },
  });
}
```


================================================
FILE: docs/1.x/concepts/partials.md
================================================
---
description: |
  Partials allow areas of a page to be updated without causing the browser to reload the page. They enable optimized fine grained UI updates and can be used to do client-side navigation.
---

Partials allow areas of the page to be updated with new content by the server
without causing the browser to reload the page. They make your website feel more
app-like because only the parts of the page that need to be updated will be
updated.

## Enabling partials

Partials are enabled by adding a `f-client-nav` attribute to an HTML element and
wrapping one or more areas in the page with a
`<Partial name="my-partial">`-component.

The quickest way to get started is to enable partials for every page in
`routes/_app.tsx` by making the following changes.

```diff routes/_app.tsx
  import { PageProps } from "$fresh/server.ts";
+ import { Partial } from "$fresh/runtime.ts";

  export default function App({ Component }: PageProps) {
    return (
      <html>
        <head>
          <meta charset="utf-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>My Fresh app</title>
        </head>
-       <body>
+       <body f-client-nav>
+         <Partial name="body">
            <Component />
+         </Partial>
        </body>
      </html>
    );
  }
```

By adding the `f-client-nav` attribute, we enable partials for every element
beneath the `<body>`-tag. To mark an area of the page as a partial we wrap it
with a `<Partial>`-component with a unique name.

Behind the scenes, when the user clicks an `<a>`-tag, Fresh fetches the new page
and only pulls out the relevant content out of the HTML response. When it finds
a matching partial area it will update the content inside the partial.

> [info]: The `name` prop of the `<Partial>` component is expected to be unique
> among Partials. That's how Fresh knows which parts of the response need to go
> on the current page.

> [info]: Passing `f-client-nav={false}` disables client side navigation for all
> elements below the current node.

### Optimizing partial requests

By default, with `f-client-nav` set, Fresh fetches the full next page and only
picks out the relevant parts of the response. We can optimize this pattern
further by only rendering the parts we need, instead of always rendering the
full page. This is done by adding the `f-partial` attribute to a link.

```diff routes/_app.tsx
- <a href="/docs/routes">Routes</a>
+ <a href="/docs/routes" f-partial="/partials/docs/routes">Routes</a>
```

When the `f-partial` attribute is present, Fresh will navigate to the page URL
defined in the `href` attribute, but fetch the updated UI from the URL specified
in `f-partial` instead. This can be a highly optimized route that only delivers
the content you care about.

Let's use a typical documentation page layout as an example. It often features a
main content area and a sidebar of links to switch between pages of the
documentation (marked green here).

![A sketched layout of a typical documentation page with the sidebar on the left composed of green links and a main content area on the right. The main content area is labeled as Partial docs-content](/docs/1.x/fresh-partial-docs.png)

The code for such a page (excluding styling) might look like this:

```tsx routes/docs/[id].tsx
export default defineRoute(async (req, ctx) => {
  const content = await loadContent(ctx.params.id);

  return (
    <div>
      <aside>
        <a href="/docs/page1">Page 1</a>
        <a href="/docs/page2">Page 2</a>
      </aside>
      <Partial name="docs-content">
        {content}
      </Partial>
    </div>
  );
});
```

An optimal route that only renders the content instead of the outer layout with
the sidebar might look like this respectively.

```tsx routes/partials/docs/[id].tsx
import { defineRoute, RouteConfig } from "$fresh/server.ts";
import { Partial } from "$fresh/runtime.ts";

// We only want to render the content, so disable
// the `_app.tsx` template as well as any potentially
// inherited layouts
export const config: RouteConfig = {
  skipAppWrapper: true,
  skipInheritedLayouts: true,
};

export default defineRoute(async (req, ctx) => {
  const content = await loadContent(ctx.params.id);

  // Only render the new content
  return (
    <Partial name="docs-content">
      {content}
    </Partial>
  );
});
```

By adding the `f-partial` attribute we tell Fresh to fetch the content from our
newly added `/partials/docs/[id].tsx` route.

```diff routes/docs/[id].tsx
  <aside>
-   <a href="/docs/page1">Page 1</a>
-   <a href="/docs/page2">Page 2</a>
+   <a href="/docs/page1" f-partial="/partials/docs/page1">Page 1</a>
+   <a href="/docs/page2" f-partial="/partials/docs/page2">Page 2</a>
  </aside>
```

With this in place, Fresh will navigate to the new page when clicking any of the
two links and _only_ load the content rendered by our optimized partial route.

> Currently, `f-partial` is scoped to `<a>`, `<button>` and `<form>` elements.
> This might be extended to more elements in the future.

## Sending multiple Partials at the same time

A neat aspect of partials in Fresh is that a response can return as many
partials as desired. That way you can update multiple unrelated areas on your
page in one single HTTP response. A scenario where this is useful are online
shops for example.

```tsx routes/partials/cart.tsx
export default function AddToCartPartial() {
  return (
    <>
      <Partial name="cart-items" mode="append">
        {/* Render the new cart item here */}
      </Partial>
      <Partial name="total-price">
        <p>Total: {totalPrice} €</p>
      </Partial>
    </>
  );
}
```

Both partials will be applied to the current page.

## Replacement mode

By default the whole content inside a partial will be replaced, but there are
scenarios where you want to prepend or append new content instead. This can be
achieved by adding the `mode` prop to a `Partial` component.

- `replace` - Swap out the content of the existing partial (default)
- `prepend` - Insert the new content before the existing content
- `append` - Insert the new content after the existing content

Personally, we’ve found that the `append` mode is really useful when you have an
UI which displays log messages or similar list-like data.

```tsx routes/log.tsx
export default function LogView() {
  const lines = getNewLogLines();

  return (
    <Partial name="logs-list" mode="append">
      {lines.map((line) => {
        return <li key={line}>{line}</li>;
      })}
    </Partial>
  );
}
```

> [info]: When picking the `prepend` or `append` mode, make sure to add keys to
> the elements.

## Bypassing or disabling Partials

If you want to exempt a particular element from triggering a partial request
like on a particular link, form or button, you can opt out of it by setting
`f-client-nav={false}` on the element or one of the ancestor elements.

```tsx routes/index.tsx
<body f-client-nav>
  {/* This will cause a partial navigation */}
  <a href="/docs/page1">With partials</a>

  {/* This WONT cause a partial navigation */}
  <a href="/docs/page1" f-client-nav={false}>No partials</a>

  {/* This WONT cause a partial navigation on any elements below */}
  <div f-client-nav={false}>
    <div>
      <a href="/docs/page1">No partials</a>
    </div>
  </div>
</body>;
```

Whenever an element is clicked Fresh checks if it has the `f-client-nav`
attribute and if it is set to `true`. If the element itself doesn't have such an
attribute, it will check if any of the ancestor elements has it. If an element
was found with a truthy `f-client-nav` attribute a partial request will be
triggered. If there is no such attribute or if it's set to `false`, no partial
request will occur.


================================================
FILE: docs/1.x/concepts/plugins.md
================================================
---
description: Plugins can add new functionality to Fresh without requiring significant complexity.
---

Plugins can dynamically add new functionality to Fresh without exposing
significant complexity to the user. Users can add plugins by importing and
initializing them in their `main.ts` file:

```ts main.ts
import { start } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";

import twindPlugin from "$fresh/plugins/twind.ts";
import twindConfig from "./twind.config.js";

await start(manifest, {
  plugins: [
    // This line configures Fresh to use the first-party twind plugin.
    twindPlugin(twindConfig),
  ],
});
```

Currently, the only available first-party plugin is the Twind plugin.
Third-party plugins are also supported - they can be imported from any HTTP
server, like any other Deno module.

Plugin hooks are executed in the order that the plugins are defined in the
`plugins` array. This means that the first plugin in the array will be executed
first, and the last plugin in the array will be executed last. For many plugins,
this does not matter, but for some plugins it may.

## Creating a plugin

Fresh plugins are in essence a collection of hooks that allow the plugin to hook
into various systems inside of Fresh.

A Fresh plugin is just a JavaScript object that conforms to the
[Plugin](https://deno.land/x/fresh/server.ts?s=Plugin) interface. The only
required property of a plugin is its name. Names must only contain the
characters `a`-`z`, and `_`.

```ts my-plugin.ts
import { Plugin } from "$fresh/server.ts";

const plugin: Plugin = {
  name: "my_plugin",
};
```

A plugin containing only a name is technically valid, but not very useful. To be
able to do anything with a plugin, it must register some hooks, middlewares, or
routes.

### Hook: `render`

The render hook allows plugins to:

- Control timing of the synchronous render of a page.
- Inject additional CSS and JS into the rendered page.

This is commonly used to set thread local variables for the duration of the
render (for example preact global context, preact option hooks, or for style
libraries like Twind). After render is complete, the plugin can inject inline
CSS and JS modules (with attached state) into the page.

The render hook is called with the
[`PluginRenderContext`](https://deno.land/x/fresh/server.ts?s=PluginRenderContext)
object, which contains a `render()` method. This method must be invoked during
the render hook to actually render the page. It is a terminal error to not call
the `render()` method during the render hook.

The `render()` method returns a
[`PluginRenderFunctionResult`](https://deno.land/x/fresh/server.ts?s=PluginRenderFunctionResult)
object which contains the HTML text of the rendered page, as well as a boolean
indicating whether the page contains any islands that will be hydrated on the
client.

The `render` hook needs to synchronously return a
[`PluginRenderResult`](https://deno.land/x/fresh/server.ts?s=PluginRenderResult)
object. Additional CSS and JS modules can be added to be injected into the page
by adding them to `styles`, `links` and `scripts` arrays in this object. The
plugin can also replace the HTML in side the `<body>`-element of the page by
including a `htmlText` string in this object.

`styles` are injected into the `<head>` of the page as inline CSS. Each entry
can define the CSS text to inject, as well as an optional `id` for the style
tag, and an optional `media` attribute for the style tag.

`links` are injected into the `<head>` of the page as `<link>` tags. A link tag
is created for each entry, with attributes from the entry's properties.

`scripts` define JavaScript/TypeScript modules to be injected into the page. The
possibly loaded modules need to be defined up front in the `Plugin#entrypoints`
property. Each defined module must be a JavaScript/TypeScript module that has a
default export of a function that takes one (arbitrary) argument, and returns
nothing (or a promise resolving to nothing). Fresh will call this function with
the state defined in the `scripts` entry. The state can be any arbitrary JSON
serializable JavaScript value.

For an example of a plugin that uses the `render` hook, see the first-party
[Twind plugin](https://github.com/denoland/fresh/blob/1.x/plugins/twind.ts).

### Hook: `renderAsync`

This hook is largely the same as the `render` hook, with a couple of key
differences to make asynchronous style and script generation possible. It must
asynchronously return its
[`PluginRenderResult`](https://deno.land/x/fresh/server.ts?s=PluginRenderResult),
either from an `async/await` function or wrapped within a promise.

The render hook is called with the
[`PluginAsyncRenderContext`](https://deno.land/x/fresh/server.ts?s=PluginAsyncRenderContext)
object, which contains a `renderAsync()` method. This method must be invoked
during the render hook to actually render the page. It is a terminal error to
not call the `renderAsync()` method during the render hook.

This is useful for when plugins are generating styles and scripts with
asynchronous dependencies based on the `htmlText`. Unlike the synchronous render
hook, async render hooks for multiple pages can be running at the same time.
This means that unlike the synchronous render hook, you can not use global
variables to propagate state between the render hook and the renderer.

The `renderAsync` hooks start before any page rendering occurs, and finish after
all rendering is complete -- they wrap around the underlying JSX->string
rendering, plugin `render` hooks, and the
[`RenderFunction`](https://deno.land/x/fresh/server.ts?s=RenderFunction) that
may be provided to Fresh's `start` entrypoint in the `main.ts` file.

### Hook: `buildStart`

This hook is run at the start of the Fresh
[ahead-of-time build task](/docs/1.x/concepts/ahead-of-time-builds). It may be
synchronous or asynchronous.

The build start hook is called with the
[`ResolvedFreshConfig`](https://deno.land/x/fresh/src/server/types.ts?s=ResolvedFreshConfig)
object, which contains the full Fresh configuration.

This hook may be used to generate precompiled static assets. Any files saved to
the `static` subfolder of `config.build.outDir` (typically `_fresh`) will be
served the same as other [static files](/docs/1.x/concepts/static-files).

### Hook: `buildEnd`

This hook is run at the end of the Fresh
[ahead-of-time build task](/docs/1.x/concepts/ahead-of-time-builds). It may be
synchronous or asynchronous.

### Routes and Middlewares

You can create routes and middlewares that get loaded and rendered like the
normal [routes](/docs/1.x/concepts/routes) and
[middlewares](/docs/1.x/concepts/middleware).

The plugin routes and middlewares need a defined path in the format of a file
name without a filetype inside the routes directory(E.g. `blog/index`,
`blog/[slug]`).

For more examples see the [Concepts: Routing](/docs/1.x/concepts/routing) page.

To create a middleware you need to create a `MiddlewareHandler` function.

And to create a route you can create both a Handler and/or component.

Below is an example plugin that creates a route and middleware

```ts my-route-and-middleware-plugin.ts
import { MiddlewareHandlerContext, Plugin } from "$fresh/server.ts";
import { handler as testMiddleware } from "./sample_routes/_middleware.ts";
import { SimpleRoute } from "./sample_routes/simple-route.tsx";
export type { Options };

interface Options {
  title: string;
}
export type PluginMiddlewareState = {
  num: number;
  test: string;
};

const twoPointlessMiddlewares = [
  async (
    _req: Request,
    ctx: MiddlewareHandlerContext<PluginMiddlewareState>,
  ) => {
    ctx.state.num = ctx.state.num === undefined ? 1 : ctx.state.num + 1;
    return await ctx.next();
  },
  async (
    _req: Request,
    ctx: MiddlewareHandlerContext<PluginMiddlewareState>,
  ) => {
    ctx.state.num = ctx.state.num === undefined ? 1 : ctx.state.num + 1;
    return await ctx.next();
  },
];

export default function routePlugin(
  options: Options,
): Plugin<PluginMiddlewareState> {
  return {
    name: "routePlugin",
    middlewares: [{
      middleware: { handler: testMiddleware },
      path: "/",
    }, {
      middleware: {
        handler: twoPointlessMiddlewares,
      },
      path: "lots-of-middleware",
    }],
    routes: [
      { path: "no-leading-slash-here", component: SimpleRoute },
    ],
  };
}
```

### Islands

Islands from plugins can be loaded by specifying a list of file paths in your
plugin. Those files will be treated by Fresh as if they had been placed inside
the `islands/` directory. They will be processed and bundled for the browser in
the same way.

```tsx my-island-plugin.ts
import { Plugin } from "$fresh/server.ts";

export default function myIslandPlugin(): Plugin {
  return {
    name: "my-island-plugin",
    islands: {
      baseLocation: import.meta.url,
      paths: [
        "./plugin/MyPluginIsland.tsx",
        "./plugin/OtherPluginIsland.tsx",
      ],
    },
  };
}
```


================================================
FILE: docs/1.x/concepts/routes.md
================================================
---
description: |
  Routes are the basic building block of Fresh applications. They are used to define the behaviour the application when a given path is requested.
---

At their core, routes describe how a request for a given path should be handled,
and what the response should be. To do this, routes have two main parts: the
handler, and the component. A route can have either one, or both, but never
neither.

The handler is a function that is called for every request to the route. It
needs to return a response that is then sent to the client. The response could
be anything: a plain text string, a JSON object, an HTML page, a WebSocket
connection, a streaming file, or pretty much anything else. The handler is
passed a `render` function that it can call to invoke rendering a component.

The component is the template for a page. It is a JSX element that is rendered
on the server. The page component gets passed props that can be used by it to
determine exactly what should be rendered. By default components receive props
consisting of: the request URL, the matching route (as a string), the matches
from the URL pattern match, any state set by middleware, and any data passed to
the handler's `render` function.

## Handler route

Let's look at a basic route that returns a plain text string:

```tsx routes/plain.tsx
import { FreshContext, Handlers } from "$fresh/server.ts";

export const handler: Handlers = {
  GET(_req: Request, _ctx: FreshContext) {
    return new Response("Hello World");
  },
};
```

To define a handler, one needs to export a `handler` function or object from the
route module. If the handler is an object, each key in the object is the name of
the HTTP method that the handler should be called for. For example the `GET`
handler above is called for `GET` requests. If the handler is a function, it is
called for all requests regardless of the method. If an HTTP method does not
have a corresponding handler, a 405 HTTP error is returned.

## Component route

Now, let's render some HTML using the route component:

```tsx routes/html.tsx
import { PageProps } from "$fresh/server.ts";

export default function Page(props: PageProps) {
  return <div>You are on the page '{props.url.href}'.</div>;
}
```

The page component needs to be the default export of the route module. It is
passed props that can be used to render the page.

As you can see in the second example, if no handler is explicitly defined a
default handler is used that just renders out the page component if present. You
can also override the default handler though to modify how exactly rendering
should work.

## Mixed handler and component route

In the below example, a custom handler is used to add a custom header to the
response after rendering the page component.

```tsx routes/html.tsx
import { FreshContext, Handlers, PageProps } from "$fresh/server.ts";

export const handler: Handlers = {
  async GET(_req: Request, ctx: FreshContext) {
    const resp = await ctx.render();
    resp.headers.set("X-Custom-Header", "Hello World");
    return resp;
  },
};

export default function Page(props: PageProps) {
  return <div>You are on the page '{props.url.href}'.</div>;
}
```

## Async route components

Having a separate route handler and component function is nice, when you want to
test these in isolation, but can become a bit cumbersome to maintain. They
require some additional indirection of declaring an interface for the component
`Data` when you're passing it around through `ctx.render()`.

```tsx routes/page.tsx
interface Data {
  foo: number;
}

export const handler: Handlers<Data> = {
  async GET(req, ctx) {
    const value = await loadFooValue();
    return ctx.render({ foo: value });
  },
};

export default function MyPage(props: PageProps<Data>) {
  return <p>foo is: {props.data.foo}</p>;
}
```

When a route has both a component and a `GET` handler, they are typically very
closely coupled. With async route components you can merge the two together and
avoid having to create the `Data` interface boilerplate.

```tsx routes/page.tsx
// Async route component
export default async function MyPage(req: Request, ctx: RouteContext) {
  const value = await loadFooValue();
  return <p>foo is: {value}</p>;
}
```

The code gets a little shorter with async route components. Conceptually, you
can think of async route components inlining the `GET` handler into the
component function. Note, that you can still add additional HTTP handlers in the
same file like before.

```tsx routes/page.tsx
export const handler: Handlers = {
  async POST(req) {
    // ... do something here
  },
};

export default async function MyPage(req: Request, ctx: RouteContext) {
  const value = await loadFooValue();
  return <p>foo is: {value}</p>;
}
```

### Returning Response objects

Quite often a route handler needs to render a 404 page or bail out of rendering
in another manner. This can be done by returning a `Response` object.

```tsx route/page.tsx
// Async route component
export default async function MyPage(req: Request, ctx: RouteContext) {
  const value = await loadFooValue();

  // Return 404 if `value` is null
  if (value === null) {
    return ctx.renderNotFound();
  }

  // Returning a response object directly works too
  if (value === "redirect") {
    const headers = new Headers();
    headers.set("location", "/some-other-page");
    return new Response(null, {
      status: 302,
      headers,
    });
  }

  return <p>foo is: {value}</p>;
}
```

### Define helper

To make it a little quicker to write async routes, Fresh ships with a
`defineRoute` helper which automatically infers the correct types for the
function arguments.

```tsx routes/hello.tsx
import { defineRoute } from "$fresh/server.ts";

export default defineRoute(async (req, ctx) => {
  const data = await loadData();

  return (
    <div class="page">
      <h1>Hello {data.name}</h1>
    </div>
  );
});
```


================================================
FILE: docs/1.x/concepts/routing.md
================================================
---
description: |
  File based routing is the simplest way to do routing in Fresh apps. Additionally custom patterns can be configured per route.
---

Routing is the mechanism that determines what route a given incoming request is
handled by. Fresh routes requests based on their URL path. By default routes
specify which paths they are invoked for using the name of the file. Routes can
also define a custom [URL pattern][urlpattern] to match against for more
advanced use cases.

The file based routing in Fresh is very similar to the file based routing seen
in other frameworks, namely Next.js. File names are used to determine which
route a given request should be handled by. The pattern is determined based on
the path of the file on disk, relative to the `routes/` directory.

File names are mapped to route patterns as follows:

- File extensions are ignored.
- Literals in the file path are treated as string literals to match.
- Files named `<path>/index.<ext>` behave identically to a file named
  `<path>.<ext>`.
- Path segments can be made dynamic by surrounding an identifier with `[` and
  `]`.
- Paths where the last path segment follows the structure `[...<ident>]` are
  treated as having a wildcard suffix.

Here is a table of file names, which route patterns they map to, and which paths
they might match:

| File name                   | Route pattern          | Matching paths                          |
| --------------------------- | ---------------------- | --------------------------------------- |
| `index.ts`                  | `/`                    | `/`                                     |
| `about.ts`                  | `/about`               | `/about`                                |
| `blog/index.ts`             | `/blog`                | `/blog`                                 |
| `blog/[slug].ts`            | `/blog/:slug`          | `/blog/foo`, `/blog/bar`                |
| `blog/[slug]/comments.ts`   | `/blog/:slug/comments` | `/blog/foo/comments`                    |
| `old/[...path].ts`          | `/old/:path*`          | `/old/foo`, `/old/bar/baz`              |
| `docs/[[version]]/index.ts` | `/docs{/:version}?`    | `/docs`, `/docs/latest`, `/docs/canary` |

Advanced use-cases can require that a more complex pattern be used for matching.
A custom [URL pattern][urlpattern] can be specified in the route configuration.
This pattern will be used instead of the file path based pattern:

```ts routes/x.ts
import { RouteConfig } from "$fresh/server.ts";

export const config: RouteConfig = {
  routeOverride: "/x/:module@:version/:path*",
};

// ...
```

## Route Groups

When working with [layouts](/docs/1.x/concepts/layouts) or
[middlewares](/docs/1.x/concepts/middleware), you'll sometimes come across a
situation where you want your routes to inherit from a layout other than what's
suggested by the URL segment.

Let's illustrate that with an example:

```txt Example page layout
/about -> layout A
/career -> layout A
/archive -> layout B
/contact -> layout B
```

Without any way to group routes this is a problem because every route segment
can only have one `_layout` file.

```txt-files Project structure
<project root>
└── routes
    ├── _layout.tsx  # applies to all routes here :(
    ├── about.tsx
    ├── career.tsx
    ├── archive.tsx
    └── contact.tsx
```

We can solve this problem with route groups. A route group is a folder which has
a name that is wrapped in parentheses. For example `(info)` would be considered
a route group and so would `(marketing)`. This enables us to group related
routes in a folder and use a different `_layout` file for each group.

```txt-files Project structure
└── <root>/routes
    ├── (marketing)
    │   ├── _layout.tsx  # only applies to about.tsx and career.tsx
    │   ├── about.tsx
    │   └── career.tsx
    └── (info)
        ├── _layout.tsx  # only applies to archive.tsx and contact.tsx
        ├── archive.tsx
        └── contact.tsx
```

> [warn]: Be careful about routes in different groups which match to the same
> URL. Such scenarios will lead to ambiguity as to which route file should be
> picked.
>
> ```txt-files Project structure
> └── <root>/routes
>     ├── (group-1)
>     │   └── about.tsx  # Bad: Maps to same `/about` url
>     └── (group-2)
>         └── about.tsx  # Bad: Maps to same `/about` url
> ```

[urlpattern]: https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API

## Co-location

If you want to store components and islands closer to their routes, you may want
to use co-location.

When the name of a route group folder starts with an underscore, like
`(_components)`, Fresh will ignore that folder and it’s effectively treated as
private. This means you can use these private route folders to store components
related to a particular route.

Following the above example, say you have some components you only want to use
in your marketing pages, you could create a route group folder `(_components)`
to house these.

The one special name is `(_islands)` which tells Fresh to treat all files in
that folder as an island.

```txt-files Project structure
└── <root>/routes
    ├── (marketing)
    │   ├── _layout.tsx
    │   ├── about.tsx
    │   ├── career.tsx
    │   ├── (_components)
    │   │   └── newsletter-cta.tsx
    │   └── (_islands)
    │       └── interactive-stats.tsx # Fresh treats this as an island
    └── shop
        ├── (_components)
        │   └── product-card.tsx
        └── (_islands)
            └── cart.tsx # Fresh treats this as an island
```

Combined together, this gives you the ability to organise your code on a feature
basis and put all related components, islands or anything else into a shared
folder.


================================================
FILE: docs/1.x/concepts/server-components.md
================================================
---
description: |
  Fresh's architecture is designed to leverage server components by default.
---

If you've read about Fresh's [architecture](/docs/1.x/concepts/architecture)
then you know that it's based on the islands architecture pattern. The flip side
of this is that everything else is, by default, a server component. When you
[create a route](/docs/1.x/getting-started/create-a-route), all of the
components used are rendered on the server. No JavaScript is sent to the client,
unless you specifically include something from the `/islands/` folder.

Internally, Fresh's rendering heavily leverages
[preact-render-to-string](https://github.com/preactjs/preact-render-to-string).
This is the exact library mentioned on Preact's
[Server-Side Rendering](https://preactjs.com/guide/v10/server-side-rendering/)
article.


================================================
FILE: docs/1.x/concepts/server-configuration.md
================================================
---
description: |
  The ability to configure the core Fresh server leads to its flexibility.
---

In this page we discuss how the server can be configured during startup.

The signature of the primary method looks like this:

```ts main.ts
export async function start(manifest: Manifest, config: FreshConfig = {});
```

## Configuration

`Manifest` comes from `fresh.gen.ts`, so nothing to do there. `config` is where
things get interesting.
[`FreshConfig`](https://deno.land/x/fresh/server.ts?s=FreshConfig) looks like
this:

```ts fresh 🍋
export interface FreshConfig {
  build?: {
    /**
     * The directory to write generated files to when `dev.ts build` is run.
     * This can be an absolute path, a file URL or a relative path.
     */
    outDir?: string;
    /**
     * This sets the target environment for the generated code. Newer
     * language constructs will be transformed to match the specified
     * support range. See https://esbuild.github.io/api/#target
     * @default {"es2022"}
     */
    target?: string | string[];
  };
  render?: RenderFunction;
  plugins?: Plugin[];
  staticDir?: string;
  router?: RouterOptions;
  server?: Partial<Deno.ServeTlsOptions>;
}
```

And for completeness here are the remaining two types:

```ts fresh 🍋
export type RenderFunction = (
  ctx: RenderContext,
  render: InnerRenderFunction,
) => void | Promise<void>;

export interface RouterOptions {
  /**
   *  Controls whether Fresh will append a trailing slash to the URL.
   *  @default {false}
   */
  trailingSlash?: boolean;
  /**
   *  Configures the pattern of files to ignore in islands and routes.
   *
   *  By default Fresh will ignore test files,
   *  for example files with a `.test.ts` or a `_test.ts` suffix.
   *
   *  @default {/(?:[^/]*_|[^/]*\.|)test\.(?:ts|tsx|mts|js|mjs|jsx|)\/*$/}
   */
  ignoreFilePattern?: RegExp;
  /**
   * Serve fresh from a base path instead of from the root.
   *   "/foo/bar" -> http://localhost:8000/foo/bar
   * @default {undefined}
   */
  basePath?: string;
}
```

## Build

### outDir

As the comment suggests, this can be used to configure where generated files are
written:

```tsx dev.ts
await dev(import.meta.url, "./main.ts", {
  build: {
    outDir: Deno.env.get("FRESH_TEST_OUTDIR") ?? undefined,
  },
});
```

### target

This should be a valid ES Build target.

```tsx dev.ts
await dev(import.meta.url, "./main.ts", {
  build: {
    target: "es2015",
  },
});
```

## Plugins

See the [docs](/docs/1.x/concepts/plugins) on this topic for more detail. But as
a quick example, you can do something like this to load plugins:

```ts main.ts
await start(manifest, { plugins: [twindPlugin(twindConfig)] });
```

## StaticDir

This allows you to specify the location where your site's static assets are
stored. Here's an example:

```ts main.ts
await start(manifest, { staticDir: "./custom_static" });
```

## Render

This is by far the most complicated option currently available. It allows you to
configure how your components get rendered.

## RouterOptions

### TrailingSlash

By default Fresh uses URLs like `https://www.example.com/about`. If you'd like,
you can configure this to `https://www.example.com/about/` by using the
`trailingSlash` setting.

```ts main.ts
await start(manifest, { router: { trailingSlash: true } });
```

### ignoreFilePattern

By default Fresh ignores test files which are co-located next routes and
islands. If you want, you can change the pattern Fresh uses ignore these files

### basePath

This setting allows you to serve a Fresh app from sub-path of a domain. A value
of `/foo/bar` would serve the app from `http://localhost:8000/foo/bar` instead
of `http://localhost:8000/` for example.

The `basePath` will be automatically applied to absolute links in your app. For
example, when the `basePath` is `/foo/bar`, linking to `/about` will
automatically become `/foo/bar/about`.

```tsx
<a href="/about">About</a>;
```

Rendered HTML:

```html
<a href="/foo/bar/about">About</a>
```

The `basePath` is also applied to the `src` and `srcset` attribute of
`<img>`-tags, the `href` attribute of `<link>` and the `src` attribute of
`<script>` tags.

## Server

Now that Deno has stabilized
[Deno.serve](https://docs.deno.com/api/deno/~/Deno.serve) and Fresh has switched
to using this API, all server configuration options are embedded in `server`
inside the `FreshConfig`. The fully expanded set of parameters looks like this:

```ts
server: {
  /** Server private key in PEM format */
  cert: string;

  /** Cert chain in PEM format */
  key: string;

  /** The port to listen on.
   *
   * @default {8000} */
  port?: number;

  /** A literal IP address or host name that can be resolved to an IP address.
   *
   * __Note about `0.0.0.0`__ While listening `0.0.0.0` works on all platforms,
   * the browsers on Windows don't work with the address `0.0.0.0`.
   * You should show the message like `server running on localhost:8080` instead of
   * `server running on 0.0.0.0:8080` if your program supports Windows.
   *
   * @default {"0.0.0.0"} */
  hostname?: string;

  /** An {@linkcode AbortSignal} to close the server and all connections. */
  signal?: AbortSignal;

  /** Sets `SO_REUSEPORT` on POSIX systems. */
  reusePort?: boolean;

  /** The handler to invoke when route handlers throw an error. */
  onError?: (error: unknown) => Response | Promise<Response>;

  /** The callback which is called when the server starts listening. */
  onListen?: (params: { hostname: string; port: number }) => void;
}
```

Use these to configure your server as you see fit.


================================================
FILE: docs/1.x/concepts/static-files.md
================================================
---
description: |
  Fresh has built-in support for serving static files. This is useful for serving images, CSS, and other static assets.
---

Fresh automatically serves static assets placed in a `static/` directory in the
project root. These assets are served at the root of the webserver, with a
higher priority than routes. This means that if a given request matches a file
in the `static/` folder, it is always served, even if there is a route that
would also match the request.

Static asset responses automatically get a `content-type` header assigned based
on the file extension of the file on disk. Assets are also automatically
streamed from disk to the client to improve performance and efficiency for both
user and server.

Fresh also adds an `etag` header to assets automatically and handles the
`If-None-Match` header for incoming requests.

### Caching

By default, no caching headers are added to assets. This can be disadvantageous
in many scenarios, so Fresh makes it easy to serve assets with long cache
lifetimes too.

The first approach to do this is manual. The client runtime exports an `asset`
function that takes an absolute path to the static asset and returns a "locked"
version of this path that contains a build ID for cache busting. When the asset
is requested at this "locked" path, it will be served with a cache lifetime of
one year.

```tsx routes/page.tsx
import { asset } from "$fresh/runtime.ts";

export default function Page() {
  return (
    <p>
      <a href={asset("/brochure.pdf")}>View brochure</a>
    </p>
  );
}
```

Fresh also does this automatically for `src` and `srcset` attributes in `<img>`
and `<source>` HTML tags. These will automatically use "locked" paths if Fresh
deems it safe to do so. You can always opt out of this behaviour per tag, by
adding the `data-fresh-disable-lock` attribute.

```tsx routes/user.tsx
{/* Locked URL source */}
<img src="/user.png" />;

{/* Preserve URL source and disable lock */}
<img src="/user.png" data-fresh-disable-lock />;
```


================================================
FILE: docs/1.x/concepts/updating.md
================================================
---
description: |
  New versions of Fresh are regularly released. This page explains how to update your project.
---

Fresh consists of multiple pieces which are independently versioned and
released.

- Fresh (https://deno.land/x/fresh)
- Preact (https://esm.sh/preact)
- preact-render-to-string (https://esm.sh/preact-render-to-string)

Some plugins also have their own dependencies that can be updated independently.

- Twind (https://esm.sh/twind) (for the twind plugin)

For the most part these pieces can be updated independently. Certain versions of
Fresh may require a minimum version of a given dependency. This is documented
below.

| Fresh version | Preact            | preact-render-to-string | Deno      |
| ------------- | ----------------- | ----------------------- | --------- |
| 1.0.0-1.0.2   | >=10.8.1 <11.0.0  | >=5.2.0 <6.0.0          | >= 1.23.0 |
| 1.1.0-1.1.5   | >=10.8.1 <11.0.0  | >=5.2.0 <6.0.0          | >= 1.25.0 |
| 1.2.0         | >=10.15.0 <11.0.0 | >=6.1.0                 | >= 1.25.0 |

## Updating dependencies

To update your dependencies, you have two options:

- Run the Fresh updater to update your project dependencies.
- Manually update the dependency versions in your `deno.json` file.

### Auto updater

The auto updater is a command line tool that will update your project's
`deno.json` file to the latest versions of Fresh and its dependencies. It may
also contain code mods for your project that will update your code to the latest
recommended patterns for Fresh projects.

To run the auto updater, run the following command from the root of your
project:

```sh Terminal
$ deno run -A -r https://fresh.deno.dev/update
```

You will be prompted to confirm the changes that will be made to your project.

### Manual update

To manually update your project's dependencies, you can edit the `deno.json`
file in the root of your projects directory. Dependency versions are encoded
into the URLs in this file. For example, here is how to update a project from
Fresh 1.0.2 to 1.1.3, and update Preact to the latest version:

```diff deno.json
  {
    "imports": {
-     "$fresh/": "https://deno.land/x/fresh@1.0.2/",
+     "$fresh/": "https://deno.land/x/fresh@1.1.5/",

-     "preact": "https://esm.sh/preact@10.8.1",
-     "preact/": "https://esm.sh/preact@10.8.1/",
+     "preact": "https://esm.sh/preact@10.11.0",
+     "preact/": "https://esm.sh/preact@10.11.0/",

-     "preact-render-to-string": "https://esm.sh/*preact-render-to-string@5.2.0",
+     "preact-render-to-string": "https://esm.sh/*preact-render-to-string@6.1.0",

      "twind": "https://esm.sh/twind@0.16.17",
      "twind/": "https://esm.sh/twind@0.16.17/"
    }
  }
```

## Automatic update checks

Fresh will periodically check if a new Fresh version is available if it's
running outside of CI. This happens once per day and can be disabled by setting
the `FRESH_NO_UPDATE_CHECK=true` environment variable.

## Code mods

Code mods are small scripts that can be run to update your project's code to
match the latest recommended patterns for Fresh projects. Code mods can be run
through the auto updater. Sometimes the code mod can not cover all cases, so you
may need to manually update some code. This section explains the code mods
currently available.

### Classical JSX -> Automatic JSX

> This code mod is only available in Fresh 1.1.0 and above.

The classical JSX transform that relies on a `/** @jsx h */` pragma is no longer
the recommended way to use JSX in Fresh projects. Instead, starting with version
1.1.0, Fresh projects should use the automatic JSX transform that requires no
JSX pragma or preact import.

```diff routes/hello-world.tsx
- /** @jsx h */
- import { h } from "preact";

  export default function Page() {
    return <div>Hello world!</div>;
  }
```

This code mod will update your deno.json file to include the relevant compiler
options to enable the automatic JSX transform. It will then go through your
project and remove any `/** @jsx h */` pragmas and `import { h } from "preact"`
statements.

### Classic twind -> Twind plugin

> This code mod is only available in Fresh 1.1.0 and above.

Fresh version 1.1.0 introduced a new plugin for using twind with Fresh. This
plugin is much nicer to use than the raw twind integration that was previously
available.

This code mod will update your project to use the new twind plugin. It will
update your `main.ts` file to import the twind plugin and add it to the plugins
array. It will also update your files to remove many unnecessary uses of the
`tw` function, and remove unnecessary twind imports. While the code mod can
handle most cases, you may need to manually update some code. Additionally you
will need to manually update your `twind.config.ts` if you use a custom
configuration.


================================================
FILE: docs/1.x/examples/active-links.md
================================================
---
description: |
  Style active links with ease in Fresh
---

Fresh automatically enhances the accessibility of `<a>` elements by adding the
aria-current attribute when rendering links that match the current URL. This
attribute is recognized by assistive technologies and clearly indicates the
current page within a set of pages.

- `aria-current="page"` - Added to links with an exact path match, enhancing
  accessibility by indicating the current page to assistive technologies.

As we aim to improve accessibility, we encourage the use of `aria-current` for
styling current links where applicable.

## Styling with CSS

The `aria-current` attribute is easily styled with CSS using attribute
selectors, providing a native way to visually differentiate the active link.

```css static/styles.css
/* Give links pointing to the current page a green color */
a[aria-current="page"] {
  color: green;
}

/* Color all ancestor links of the current page */
a[aria-current="true"] {
  color: peachpuff;
}
```

## Tailwind / Twind

In Tailwind or similar CSS frameworks like Twind, you can apply styles to
elements with the aria-current attribute using bracket notation in your class
definitions. However, the specific syntax varies slightly between Tailwind and
Twind. For Tailwind, use the syntax:

```tsx component/Menu.tsx
function Menu() {
  return (
    <a href="/foo" class="aria-[current]:text-green-600">
      Link to some page
    </a>
  );
}
```

For Twind, the syntax is:

```tsx component/Menu.tsx
function Menu() {
  return (
    <a href="/foo" class="[aria-current]:text-green-600">
      Link to some page
    </a>
  );
}
```

### Twind Plugin

The original twind plugin (`import twindPlugin from "$fresh/plugins/twind.ts";`)
supports the above style:

```tsx routes/page.tsx
class="[aria-current='page']:text-green-600"
```

### TwindV1 Plugin

The new twind plugin (`import twindPlugin from "$fresh/plugins/twindv1.ts";`)
requires a slightly different syntax (note the position of the left bracket):

```tsx routes/page.tsx
class="aria-[current='page']:text-green-600"
```


================================================
FILE: docs/1.x/examples/authentication-with-supabase.md
================================================
---
description: |
  Learn how to implement the PKCE authentication flow using Supabase.
---

Fresh is a great tool for quickly building lightweight, server-side rendered web
apps and Supabase provides an easy way to add authentication (and/or a
PostgreSQL database backend) to your app.

In this example, we'll create a small app that implements the PKCE
authentication flow using Supabase.

The PKCE authentication flow is designed specifically for applications that
cannot store a client secret, such as native mobile apps or server-side rendered
web apps. You can read up on the specifics of PKCE
[here](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce)
or have a look at
[its specification](https://datatracker.ietf.org/doc/html/rfc7636). Our example
is based on the information you can piece together from the
[Supabase documentation](https://supabase.com/docs/guides/auth/server-side/oauth-with-pkce-flow-for-ssr)
on the topic.

The purpose of the example app we're building here is to showcase the basic
building blocks of an implementation. As such, it is limited in functionality
and purposefully leaves out things like
[password resets](https://supabase.com/docs/guides/auth/server-side/email-based-auth-with-pkce-flow-for-ssr),
[proper error handling](https://fresh.deno.dev/docs/1.x/concepts/error-pages) as
well as validating input form data. You can find the
[full code here](https://github.com/morlinbrot/supa-fresh-pkce), where the
missing functionality is implemented.

## Supabase

First of all, we need a Supabase account
[which can be created for free here](https://supabase.com/). A handy way to
supply the credentials to our app is via `.env` file (never check in `.env`
files to version control).

```txt .env.example
SUPABASE_URL=https://<projectName>.supabase.co
SUPABASE_ANON_KEY=<api_key>
```

Update the imports section of your `deno.json` file to include the following:

```json deno.json
"imports": {
  "supabase": "npm:@supabase/supabase-js@2",
  "supabase/ssr": "npm:@supabase/ssr",
}
```

Since Deno 1.38, we reading .env files is built-in and can be enabled with the
`--env` flag. Here's the complete command to run our app:

```shell
deno run --unstable-kv --allow-env --allow-read --allow-write --allow-run --allow-net --watch=static/,routes/ dev.ts
```

### `@supabase/ssr`

Supabase provides the `@supabase/ssr` package for working with its API in an SSR
context. It exposes the `createServerClient` method that we can use on the
server side. Set it up like so:

```ts lib/supabase.ts
import { deleteCookie, getCookies, setCookie } from "$std/http/cookie.ts";
import { assert } from "$std/assert/assert.ts";
import { type CookieOptions, createServerClient } from "supabase/ssr";

export function createSupabaseClient(
  req: Request,
  // Keep this optional parameter in mind, we'll get back to it.
  resHeaders = new Headers(),
) {
  const SUPABASE_URL = Deno.env.get("SUPABASE_URL");
  const SUPABASE_ANON_KEY = Deno.env.get("SUPABASE_ANON_KEY");

  assert(
    SUPABASE_URL && SUPABASE_ANON_KEY,
    "SUPABASE URL and SUPABASE_ANON_KEY environment variables must be set.",
  );

  return createServerClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
    auth: { flowType: "pkce" },
    cookies: {
      get(name: string) {
        return decodeURIComponent(getCookies(req.headers)[name]);
      },
      set(name: string, value: string, options: CookieOptions) {
        setCookie(resHeaders, {
          name,
          value: encodeURIComponent(value),
          ...options,
        });
      },
      remove(name: string, options: CookieOptions) {
        deleteCookie(resHeaders, name, options);
      },
    },
  });
}
```

Note: We are specifying the `flowType` to be `pkce` and that we're using
[`encodeURIComponent()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent)
to serialize and store the session object as a cookie.

Crucially, _we need to create a new instance of this client for each request!_

## Sign Up

In our endpoints, we can now use this client to talk to the Supabase API. Here's
the `/api/sign-up` handler:

```ts routes/api/sign-up.ts
import { FreshContext, Handlers } from "$fresh/server.ts";
import { createSupabaseClient } from "lib/supabase.ts";

export const handler: Handlers = {
  async POST(req: Request, _ctx: FreshContext) {
    const form = await req.formData();
    const email = form.get("email");
    const password = form.get("password");

    const headers = new Headers();
    headers.set("location", "/sign-in"); // Redirect to /sign-in on success.

    const supabase = createSupabaseClient(req);
    const { error } = await supabase.auth.signUp({
      email: String(email),
      password: String(password),
    });

    if (error) throw error; // Have a look at the full app for proper error handling.

    return new Response(null, { status: 303, headers });
  },
};
```

Create a form to call our API endpoint and render it at `/sign-up`:

```tsx routes/sign-up.tsx
export default function SignUpPage() {
  return (
    <form action="/api/sign-up" method="post">
      <input autofocus type="email" name="email" />
      <input type="password" name="password" />
      <button type="submit">Submit</button>
    </form>
  );
}
```

## Confirmation

To complete the sign-up process, we need a `/confirm` route to intercept
successful email confirmations:

```ts routes/api/confirm.ts
import { Handlers } from "$fresh/server.ts";
import { createSupabaseClient } from "lib/supabase.ts";

export const handler: Handlers = {
  async GET(req: Request) {
    const { searchParams } = new URL(req.url);
    const token_hash = searchParams.get("token_hash");
    const type = searchParams.get("type") as EmailOtpType | null;
    const next = searchParams.get("next") ?? "/welcome";

    const redirectTo = new URL(req.url);
    redirectTo.pathname = next;

    if (token_hash && type) {
      const supabase = createSupabaseClient(req);
      const { error } = await supabase.auth.verifyOtp({ type, token_hash });
      if (error) throw error; // Have a look at the full app for proper error handling.
    }

    redirectTo.searchParams.delete("next");
    return Response.redirect(redirectTo);
  },
};
```

Have a look at the Supabase docs on the
[details on how to configure email templates and other endpoints](https://supabase.com/docs/guides/auth/server-side/email-based-auth-with-pkce-flow-for-ssr)
like `/password-reset` you would need for a full implementation.

## Sign In

The `/api/sign-in` route is pretty straight-forward, too:

```ts routes/api/sign-in.ts
import { Handlers } from "$fresh/server.ts";
import { createSupabaseClient } from "lib/supabase.ts";

export const handler: Handlers = {
  async POST(req) {
    const form = await req.formData();
    const email = form.get("email")!;
    const password = form.get("password")!;

    const headers = new Headers();
    headers.set("location", "/");

    const supabase = createSupabaseClient(req, headers);
    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });

    if (error) throw error; // Have a look at the full app for proper error handling.

    return new Response(null, { status: 303, headers });
  },
};
```

Note: We're passing `headers` this time. The Supabase client will set the
session as a cookie for us, which we will want to pick up in the middleware that
we are writing next.

## Middleware

We can now write a middleware that will check the auth status of any request,
guarding any protected routes. You can read up on middlewares and where to put
them [in the docs](https://fresh.deno.dev/docs/1.x/concepts/middleware).

```ts routes/_middleware.ts
import { FreshContext } from "$fresh/server.ts";
import { createSupabaseClient } from "lib/supabase.ts";

export const handler = [
  async function authMiddleware(req: Request, ctx: FreshContext) {
    const url = new URL(req.url);
    const headers = new Headers();
    headers.set("location", "/");

    const supabase = createSupabaseClient(req, headers);
    // Note: Always use `getUser` instead of `getSession` as this calls the Supabase API and revalidates the token.
    const { error, data: { user } } = await supabase.auth.getUser();

    const isProtectedRoute = url.pathname.includes("secret");

    // Don't mind 401 as it just means no credentials were provided. E.g. There was no session cookie.
    if (error && error.status !== 401) throw error; // Have a look at the full app for proper error handling.

    if (isProtectedRoute && !user) {
      return new Response(null, { status: 303, headers });
    }

    ctx.state.user = user;

    return ctx.next();
  },
];
```

That's it! These are the building blocks for implementing the PKCE
authentication flow in a Fresh app using Supabase. Again, have a look at the
[full code here](https://github.com/morlinbrot/supa-fresh-pkce) for a fully
featured version of the app.


================================================
FILE: docs/1.x/examples/changing-the-src-dir.md
================================================
---
description: |
  Change the source directory to effectively manage your project.
---

When you initialize a project with `deno run -A -r https://fresh.deno.dev`,
you'll end up with a project like the following:

```txt-files Project Structure
<project root>
├── README.md
├── components
│   └── Button.tsx
├── deno.json
├── dev.ts
├── fresh.gen.ts
├── islands
│   └── Counter.tsx
├── main.ts
├── routes
│   ├── greet
│   │   ├── [name].tsx
│   ├── api
│   │   └── joke.ts
│   ├── _404.tsx
│   └── index.tsx
└── static
    ├── favicon.ico
    └── logo.svg
```

## Using a `src` directory

If you'd like your code to live in an `src` directory (or any other directory of
your choosing), then you'll need to do the following things:

1. Move all your files, except `deno.json` and `README.md`, to the `src`
   directory.
2. Modify the `start` task in `deno.json` to point to the new directory.

Here's what the diff of `deno.json` looks like:

```diff deno.json
 {
   "lock": false,
   "tasks": {
-    "start": "deno run -A --watch=static/,routes/ dev.ts"
+    "start": "deno run -A --watch=src/static/,src/routes/ src/dev.ts"
   },
   "imports": {
     "$fresh/": "file:///Users/reed/code/fresh/",
```

The resulting file structure looks like this:

```txt-files Project Structure
<project root>
├── README.md
├── deno.json
└── src
    ├── components
    │   └── Button.tsx
    ├── dev.ts
    ├── fresh.gen.ts
    ├── islands
    │   └── Counter.tsx
    ├── main.ts
    ├── routes
    │   ├── greet
    │   │   ├── [name].tsx
    │   ├── api
    │   │   └── joke.ts
    │   ├── _404.tsx
    │   └── index.tsx
    └── static
        ├── favicon.ico
        └── logo.svg
```

Success! Your code now lives elsewhere.


================================================
FILE: docs/1.x/examples/client-side-components-and-libraries.md
================================================
---
description: |
  Client side components and libraries
---

Some components depend on client environments, browser-specific features, or
dynamic user interactions, making them incompatible or non-functional during
server-side rendering.

By employing conditional rendering and state management techniques, we can
ensure graceful handling of library or data loading, improving workflow and
usability of such components.

Let's explore an example utilizing this solution with Leaflet, a popular mapping
library, in a Fresh application. The objective is to ensure the proper rendering
of Leaflet components on the client side while gracefully handling them on the
server side.

The full code is available at the end of the page

## Explanation

The first step is creating the context variable to enhance usability across
various components within a Fresh application. By initializing these variables
with a null value and integrating type references, developers can streamline the
use of client side features while adapting to scenarios where server side
rendering might not be feasible.

> [warn]: Proper typing might not be easily available, so we might need to
> define our own types or not use types at all.

```ts context.ts
export const leafletContext = createContext<typeof Leaflet | null>(null);
```

Then, we should implement a Provider Component, this will handle loading and
passing down values to be used in other components, other than that, we also
need to handle the server side case as well.

In this example, for the server side we are simply rendering a placeholder in
place of our component tree. As for the context value, we are using html tags to
inject the library on the window and a onLoad callback to set the value of our
state, and this value will be handled/shared with our other components.

> [warn]: Be careful with providers, the manner in which they load/inject both
> script and css may cause issues. Leaflet, for instance, will throw errors if
> we try to load it again.

```tsx context.ts
function LeafletProvider(props: { children: ComponentChildren }) {
  if (!IS_BROWSER) {
    return (
      <p>Leaflet must be loaded on the client. No children will render</p>
    );
  }
  const value = useSignal<typeof Leaflet | null>(null)
  return (
    <>
      {/* Load Leaflet CSS */}
      <link
        rel="stylesheet"
        href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
        integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
        crossorigin=""
      />
      {/* Load Leaflet JS */}
      <script
        onLoad={() => value.value = window.L}
        src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
        integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
        crossorigin=""
      />
      {/* Provide Leaflet context to children */}
      <leafletContext.Provider value={value}>
        {props.children}
      </LeafletContext.Provider>
    </>
  );
}
```

In order to utilize the context, call the useContext hook with the context
variable this will give us access to the value set in the Provider. Handling
cases where the context has not loaded values yet is a good practice as well, in
this way we can have a smooth integration and manipulation of client-side data
and logic on our server-side code.

```tsx component/Map.tsx
function MapComponent() {
  const leaf = useContext(leafletContext);
  if (!leaf) return <p>Context not ready. Component placeholder</p>;
  useEffect(() => {
    const map = leaf.map("map").setView(leaf.latLng(0, 0), 2);
    leaf.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
      attribution:
        '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
    }).addTo(map);
  });
  return <div id="map" class="relative w-[80vw] h-[50vh]" />;
}
```

Here is an example island encapsulating both the provider and component in order
to demonstrate a simple usage. In real cases, it's usually better to add the
Provider directly to our Page and then use Components that depend on that
provider inside it.

```tsx islands/MapIsland.tsx
export default function MapIsland() {
  return (
    <LeafletProvider>
      <MapComponent />
    </LeafletProvider>
  );
}
```

## Full code:

```tsx islands/MapIsland.tsx
import * as Leaflet from "https://esm.sh/v135/@types/leaflet@1.9.4/index.d.ts";
import { IS_BROWSER } from "$fresh/runtime.ts";
import { useContext, useEffect } from "preact/hooks";
import { ComponentChildren, createContext } from "preact";
import { useSignal } from "@preact/signals";

// Create a context to hold Leaflet data/functions
const LeafletContext = createContext<typeof Leaflet | null>(null);

// LeafletProvider component manages Leaflet loading and context
function LeafletProvider(props: { children: ComponentChildren }) {
  if (!IS_BROWSER) {
    return <p>Leaflet must be loaded on the client. No children will render</p>;
  }
  const value = useSignal<typeof Leaflet | null>(null);
  return (
    <>
      {/* Load Leaflet CSS */}
      <link
        rel="stylesheet"
        href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
        integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
        crossorigin=""
      />
      {/* Load Leaflet JS */}
      <script
        onLoad={() => value.value = window.L}
        src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
        integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
        crossorigin=""
      />
      {/* Provide Leaflet context to children */}
      <LeafletContext.Provider value={value}>
        {props.children}
      </LeafletContext.Provider>
    </>
  );
}

// MapComponent utilizes Leaflet context for rendering the map
function MapComponent() {
  const leaf = useContext(LeafletContext);
  if (!leaf) return <div>Component placeholder</div>;
  useEffect(() => {
    const map = leaf.map("map").setView(leaf.latLng(0, 0), 2);
    leaf.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
      attribution:
        '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
    }).addTo(map);
  });
  return <div id="map" class="relative w-[80vw] h-[50vh]" />;
}

// MapIsland is the parent component integrating LeafletProvider and MapComponent
export default function MapIsland() {
  return (
    <LeafletProvider>
      <MapComponent />
    </LeafletProvider>
  );
}
```


================================================
FILE: docs/1.x/examples/creating-a-crud-api.md
================================================
---
description: |
  Use HTTP CRUD methods to perform operations on resources. Learn how to use HTTP handlers to create a RESTful API.
---

The MDN [docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) are a
great resource to learn more about HTTP methods. We'll touch on the four
fundamental methods necessary to create a basic CRUD (create, read, update,
delete) API here. Additionally, we'll briefly mention CORS requests and how
`OPTIONS` comes into play.

Using HTTP methods is a common way to create a REST API. Fresh supports common
HTTP methods in handlers out of the box. Async HTTP requests are also supported.
Read more about custom handlers [here](/docs/getting-started/custom-handlers).

In this example we'll be creating a small API that uses
[Deno KV](https://deno.com/kv) to store users in a database.

Our project structure will look like this (in addition to the rest of the Fresh
code from a new project):

```txt-files Project Structure
<project root>
└── routes
    └── api
        └── users
            ├── [id].ts
            └── index.ts
```

In each section about a method, only the relevant handler will be shown. The
full files are available at the bottom for reference.

## POST

`POST` (create) is used to create a resource.

```tsx routes/api/users/index.ts
export const handler: Handlers<User | null> = {
  async POST(req, _ctx) {
    const user = (await req.json()) as User;
    const userKey = ["user", user.id];
    const ok = await kv.atomic().set(userKey, user).commit();
    if (!ok) throw new Error("Something went wrong.");
    return new Response(JSON.stringify(user));
  },
};
```

Test this with Postman (or your favorite client) with a URL like
`http://localhost:8000/api/users` and a method of `POST`. Make sure to have a
payload like:

```json Request body
{
  "id": "2",
  "name": "TestUserName"
}
```

You should receive the same thing back:

```json Response body
{ "id": "2", "name": "TestUserName" }
```

## GET

`GET` (read) is used to retrieve a resource and is by far the most common HTTP
method. You can use `GET` to fetch database content, markdown, or static files.

```tsx routes/api/users/[id].ts
export const handler: Handlers<User | null> = {
  async GET(_req, ctx) {
    const id = ctx.params.id;
    const key = ["user", id];
    const user = (await kv.get<User>(key)).value!;
    return new Response(JSON.stringify(user));
  },
};
```

Let's practice retrieving our user! A `GET` request to
`http://localhost:8000/api/users/2` should return:

```json Response body
{ "id": "2", "name": "TestUserName" }
```

## PUT (and PATCH)

`PUT` (update) and `PATCH` are used to update a resource. While similar, there
are differences and you should use the one that best suits your use case. Read
more about HTTP methods on
[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods).

The short version of it: `PUT` requires the entire object to be submitted, while
`PATCH` requires only the properties that are different to be submitted.

An example of an update endpoint using `PUT`:

```tsx routes/api/users/[id].ts
export const handler: Handlers<User | null> = {
  async PUT(req, ctx) {
    const id = ctx.params.id;
    const user = (await req.json()) as User;
    const userKey = ["user", id];
    const userRes = await kv.get(userKey);
    if (!userRes.value) return new Response(`no user with id ${id} found`);
    const ok = await kv.atomic().check(userRes).set(userKey, user).commit();
    if (!ok) throw new Error("Something went wrong.");
    return new Response(JSON.stringify(user));
  },
};
```

Time to change their name. We'll now `PUT` a request to
`http://localhost:8000/api/users/2` like:

```json Request body
{
  "id": "2",
  "name": "New Name"
}
```

We should receive:

```json Response body
{ "id": "2", "name": "New Name" }
```

If, on the other hand, we chose to implement this as a `PATCH` operation, the
request would just involve the changed property like this:

```json Response body
{
  "name": "New Name"
}
```

No need to send in the id in this case.

## DELETE

`DELETE` (delete) is used to delete a resource.

```tsx routes/api/users/[id].ts
export const handler: Handlers<User | null> = {
  async DELETE(_req, ctx) {
    const id = ctx.params.id;
    const userKey = ["user", id];
    const userRes = await kv.get(userKey);
    if (!userRes.value) return new Response(`no user with id ${id} found`);
    const ok = await kv.atomic().check(userRes).delete(userKey).commit();
    if (!ok) throw new Error("Something went wrong.");
    return new Response(`user ${id} deleted`);
  },
};
```

Try sending `DELETE` to `http://localhost:8000/api/users/2` without a body.
We'll get back:

```txt Response body
user 2 deleted
```

## OPTIONS

Options can be used for some advanced cases, including implementing preflight
request checks for complex CORS use cases. See more on the
[CORS documentation](/docs/1.x/examples/dealing-with-cors).

## Full File Reference

<details>
<summary><code>[id].ts</code></summary>

```ts routes/api/users/[id].ts
import { Handlers } from "$fresh/server.ts";

type User = {
  id: string;
  name: string;
};

const kv = await Deno.openKv();

export const handler: Handlers<User | null> = {
  async GET(_req, ctx) {
    const id = ctx.params.id;
    const key = ["user", id];
    const user = (await kv.get<User>(key)).value!;
    return new Response(JSON.stringify(user));
  },
  async DELETE(_req, ctx) {
    const id = ctx.params.id;
    const userKey = ["user", id];
    const userRes = await kv.get(userKey);
    if (!userRes.value) return new Response(`no user with id ${id} found`);
    const ok = await kv.atomic().check(userRes).delete(userKey).commit();
    if (!ok) throw new Error("Something went wrong.");
    return new Response(`user ${id} deleted`);
  },
  async PUT(req, ctx) {
    const id = ctx.params.id;
    const user = (await req.json()) as User;
    const userKey = ["user", id];
    const userRes = await kv.get(userKey);
    if (!userRes.value) return new Response(`no user with id ${id} found`);
    const ok = await kv.atomic().check(userRes).set(userKey, user).commit();
    if (!ok) throw new Error("Something went wrong.");
    return new Response(JSON.stringify(user));
  },
};
```

</details>

<details>
<summary><code>index.ts</code></summary>

```ts routes/api/users/index.ts
import { Handlers } from "$fresh/server.ts";

type User = {
  id: string;
  name: string;
};

const kv = await Deno.openKv();

export const handler: Handlers<User | null> = {
  async GET(_req, _ctx) {
    const users = [];
    for await (const res of kv.list({ prefix: ["user"] })) {
      users.push(res.value);
    }
    return new Response(JSON.stringify(users));
  },
  async POST(req, _ctx) {
    const user = (await req.json()) as User;
    const userKey = ["user", user.id];
    const ok = await kv.atomic().set(userKey, user).commit();
    if (!ok) throw new Error("Something went wrong.");
    return new Response(JSON.stringify(user));
  },
};
```

</details>


================================================
FILE: docs/1.x/examples/dealing-with-cors.md
================================================
---
description: |
  CORS enabling routes in your Fresh project.
---

So you've encountered some CORS problems and are on the hunt for the solution?
You're in the right spot.

Here's a good [resource](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
talking about CORS in general, in case you don't fully understand what's wrong.

## Simple CORS -- Middleware

As per the above link, "simple" requests involve `GET`, `HEAD`, or `POST`
requests. You can CORS enable all the routes affected by some `middleware` by
doing the following:

```ts routes/_middleware.ts
import { FreshContext } from "$fresh/server.ts";

export async function handler(req: Request, ctx: FreshContext) {
  const origin = req.headers.get("Origin") || "*";
  const resp = await ctx.next();
  const headers = resp.headers;

  headers.set("Access-Control-Allow-Origin", origin);
  headers.set("Access-Control-Allow-Credentials", "true");
  headers.set(
    "Access-Control-Allow-Headers",
    "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With",
  );
  headers.set(
    "Access-Control-Allow-Methods",
    "POST, OPTIONS, GET, PUT, DELETE",
  );

  return resp;
}
```

## Complex CORS -- Middleware

What about for one of the other HTTP methods? Then you'll need to be able to
deal with "preflight requests". Let's imagine you're trying to support a
`DELETE` route. Then you'd need to do something like this:

```ts routes/_middleware.ts
import { FreshContext } from "$fresh/server.ts";

export async function handler(req: Request, ctx: FreshContext) {
  if (req.method == "OPTIONS") {
    const resp = new Response(null, {
      status: 204,
    });
    const origin = req.headers.get("Origin") || "*";
    const headers = resp.headers;
    headers.set("Access-Control-Allow-Origin", origin);
    headers.set("Access-Control-Allow-Methods", "DELETE");
    return resp;
  }
  const origin = req.headers.get("Origin") || "*";
  const resp = await ctx.next();
  const headers = resp.headers;

  headers.set("Access-Control-Allow-Origin", origin);
  headers.set("Access-Control-Allow-Credentials", "true");
  headers.set(
    "Access-Control-Allow-Headers",
    "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With",
  );
  headers.set(
    "Access-Control-Allow-Methods",
    "POST, OPTIONS, GET, PUT, DELETE",
  );

  return resp;
}
```

These complex results require a two step process:

1. the browser makes an `OPTIONS` request to find out about the allowed methods
2. the browser makes the actual request

So you can see the middleware has some special handling to deal with `OPTIONS`
requests.

## CORS in Routes

Of course there's no reason why you need to use middleware in order to solve
this. The headers can be set directly in the
[handler](/docs/1.x/getting-started/custom-handlers) as well.


================================================
FILE: docs/1.x/examples/handling-complex-routes.md
================================================
---
description: |
  Sometimes URL based routing isn't enough.
---

The page on [routing](/docs/1.x/concepts/routing) hints at complex routing based
on URL patterns using a `RouteConfig` object. Let's dive into this in a bit more
detail.

A `RouteConfig` has a `routeOverride` string property, which makes use of the
[URL Pattern API](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API).
Here you can define named groups, wildcards, regex groups, and other bits.

## Simple Route Config

Let's look at the example from the routing page more closely. We'll flesh out
the handler so that we end up with something like the following:

```ts routes/x.tsx
import { FreshContext, RouteConfig } from "$fresh/server.ts";

export const handler = {
  GET(_req: Request, { params }: FreshContext) {
    console.log(params);
    return new Response(params.path);
  },
};

export const config: RouteConfig = {
  routeOverride: "/x/:module@:version/:path*",
};
```

Now if we hit the server with a request like
`http://localhost:8000/x/bestModule@1.33.7/asdf`, then logging the params will
show the following:

```txt Console output
{
  module: "bestModule",
  version: "1.33.7",
  path: "asdf"
}
```

## Complex Route Config

Let's look at something a bit more complex:

```ts routes/api.tsx
import { FreshContext, RouteConfig } from "$fresh/server.ts";

export const handler = {
  GET(_req: Request, { params }: FreshContext) {
    console.log(params);
    return new Response(params.path);
  },
};

export const config: RouteConfig = {
  routeOverride: "/api/db/:resource(jobs?|bar)/:id(\\d+)?",
};
```

Values are available via `params.resource` and `params.id`.

Here are some example URLs that match this:

- `/api/db/bar/1`
- `/api/db/jobs/1`
- `/api/db/job/1`
- `/api/db/job`
- `/api/db/jobs`
- `/api/db/bar`

Here are some that don't:

- `/api/db/other/123`
- `/api/db/jobs/abc`
- `/api/db`

## Regex

At this point is should be clear that this is essentially an exercise in
understanding regex. There are [numerous](https://regexr.com/)
[resources](https://regex101.com/) [available](https://chat.openai.com/) for
getting assistance with regex.


================================================
FILE: docs/1.x/examples/index.md
================================================
---
description: |
  In this chapter of the Fresh documentation, you can find examples of features that you may like in your Fresh project.
---

In this chapter of the Fresh documentation, you can find examples of features
that you may like in your Fresh project. If there's a specific example you'd
like to see here, please open
[a GitHub discussion](https://github.com/denoland/fresh/discussions/new?category=ideas).

- [Modifying the `<head>`](./examples/modifying-the-head)
- [Setting the language](./examples/setting-the-language)
- [Writing tests](./examples/writing-tests)
- [Changing the source directory](./examples/changing-the-src-dir)
- [Initializing the server](./examples/init-the-server)
- [Using Fresh canary version](./examples/using-fresh-canary-version)
- [Dealing with CORS](./examples/dealing-with-cors)
- [Creating a CRUD API](./examples/creating-a-crud-api)
- [Handling complex routes](./examples/handling-complex-routes)
- [Rendering markdown](./examples/rendering-markdown)
- [Sharing state between islands](./examples/sharing-state-between-islands)
- [Using CSP](./examples/using-csp)


================================================
FILE: docs/1.x/examples/init-the-server.md
================================================
---
description: |
  For when you have some complicated setup that needs to be performed once.
---

Let's pretend you've just initialized a new Fresh project. You want to do some
complicated setup that runs once, before the server is started. This is,
fortunately, quite easy. Here's how. Modify your `fresh.config.ts` like this:

```diff fresh.config.ts
 import twindConfig from "./twind.config.ts";
+import { Context } from "./routes/_middleware.ts";
+
+await Context.init();

 export default defineConfig({
   plugins: [twindPlugin(twindConfig)],
```

So your full `fresh.config.ts` should look like this:

```ts fresh.config.ts
import { defineConfig } from "$fresh/server.ts";
import twindPlugin from "$fresh/plugins/twind.ts";
import twindConfig from "./twind.config.ts";
import { Context } from "./routes/_middleware.ts";

await Context.init();

export default defineConfig({
  plugins: [twindPlugin(twindConfig)],
});
```

But what's going on in this new `_middleware.ts` we've created?

```ts routes/_middleware.ts
import { FreshContext } from "$fresh/server.ts";

export interface State {
  context: Context;
}

export class Context {
  private static context: Context;
  private complicatedStartupValue: number;

  public constructor() {
    console.log("i'm logged during initialization, and not during handling!");
    // presumably this involves connecting to a
    // database or doing some heavy computation
    this.complicatedStartupValue = 42;
  }

  public static async init() {
    Context.context = new Context();
  }

  public static instance() {
    if (this.context) return this.context;
    else throw new Error("Context is not initialized!");
  }
}

export async function handler(
  _req: Request,
  ctx: FreshContext<State>,
) {
  ctx.state.context = Context.instance();
  if (ctx.destination === "route") {
    console.log("i'm logged during a request!");
    console.log(ctx.state.context);
  }
  const resp = await ctx.next();
  return resp;
}
```

So now in this `handler` (or any other `handler` functions you create) you can
have access to the complicated initialization step by calling
`Context.instance()`.

## Proving it out

### Dev

When you run `deno task start` you should see the following output:

```txt Terminal output
Task start deno run -A --watch=static/,routes/ dev.ts
Watcher Process started.
i'm logged during initialization, and not during handling!
The manifest has been generated for 6 routes and 1 islands.

 🍋 Fresh ready
    Local: http://localhost:8000/
```

Going to `http://localhost:8000/` should produce:

```txt Terminal output
i'm logged during a request!
Context { complicatedStartupValue: 42 }
```

### Build

When you run `deno task build` you should see:

```txt Terminal output
Task build deno run -A dev.ts build
i'm logged during initialization, and not during handling!
The manifest has been generated for 6 routes and 1 islands.
Assets written to: /path/to/my/project/_fresh
```

There's no handling of routes associated with this, but note that the
initialization occurred.

### Preview

Finally when you run `deno task preview` you should see:

```txt Terminal output
Task preview deno run -A main.ts
i'm logged during initialization, and not during handling!
Using snapshot found at /Users/reed/code/temp/1763/_fresh

 🍋 Fresh ready
    Local: http://localhost:8000/
```

Going to `http://localhost:8000/` should produce:

```txt Terminal output
i'm logged during a request!
Context { complicatedStartupValue: 42 }
```


================================================
FILE: docs/1.x/examples/migrating-to-tailwind.md
================================================
---
description: |
  Migrating from twind to Tailwind CSS
---

Starting with version 1.6 Fresh comes with a proper Tailwind CSS plugin out of
the box. When you create a new Fresh project, checking the Tailwind CSS option
will now install the Tailwind CSS plugin instead of twind like it did before.

## Requirements before migrating

The tailwind plugin requires Fresh's
[ahead of time builds](/docs/1.x/concepts/ahead-of-time-builds) to be set up,
otherwise it won't work. Make sure to switch your projects to ahead of time
builds in your project before continuing this guide. If your project is already
configured to use ahead of time builds, then you're good to go.

## Migrating to Tailwind CSS

1. Create a `<project>/tailwind.config.ts` file in your project folder:

```ts tailwind.config.ts
import { type Config } from "tailwindcss";

export default {
  content: [
    "{routes,islands,components}/**/*.{ts,tsx}",
  ],
} satisfies Config;
```

2. Create a css file in your static directory `<project>/static/styles.css`:

```css static/styles.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

3. Add the created stylesheet in your HTML in `<project>/routes/_app.tsx`:

```diff routes/_app.tsx
  import { AppProps } from "$fresh/server.ts";
  
  export default function App({ Component }: AppProps) {
    return (
      <html>
        <head>
          <meta charset="utf-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>My Fresh Project</title>
+         <link rel="stylesheet" href="/styles.css" />
        </head>
        <body>
          <Component />
      </body>
      </html>
    );
  }
```

4. Replace the `twind` plugin with `tailwind`

```diff fresh.config.ts
  import { defineConfig } from "$fresh/server.ts";
- import twind from "$fresh/plugins/twind.ts";
+ import tailwind from "$fresh/plugins/tailwind.ts";

  export default defineConfig({
-   plugins: [twind()],
+   plugins: [tailwind()],
  });
```

5. Update your `deno.json` file and add the following `tailwindcss` imports. To
   make the
   [vscode Tailwind CSS extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)
   work, we also need to set `"nodeModulesDir": "manual"`. This will create a
   `node_modules` directory in your project folder when you run `deno install`.

```diff deno.json
  {
+   "nodeModulesDir": "manual",
    "imports": {
      "$fresh/": "https://deno.land/x/fresh@1.5.2/",
      "preact": "https://esm.sh/preact@10.22.0",
      "preact/": "https://esm.sh/preact@10.22.0/",
-     "twind": "https://esm.sh/twind@0.16.19",
-     "twind/": "https://esm.sh/twind@0.16.19/"
+     "tailwindcss": "npm:tailwindcss@3.4.1"
    }
  }
```

6. Add `node_modules` to your `.gitignore` or create one if the file is not
   present in your project root directory.

```diff .gitignore
+ node_modules/
```

That's it! Now you can use Tailwind CSS in your project.

> [info]: If you're a vscode user, be sure to install the
> [official Tailwind CSS extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)
> to get full intellisense support. For it to work you also need to set
> `"nodeModulesDir": "manual"` in your `deno.json`.

> [warn]: Tailwind CSS doesn't support the grouping syntax from twind:
> `text(lg uppercase gray-100)`. These need to be rewritten to their expanded
> values like `text-lg uppercase text-gray-100`. Selecting `data-*` or `aria-*`
> attributes works a little different with Tailwind CSS as well.
>
> | Twind                       | Tailwind CSS                |
> | --------------------------- | --------------------------- |
> | `[data-current]:bg-red-600` | `data-[current]:bg-red-300` |
> | `[aria-current]:bg-red-600` | `aria-[current]:bg-red-300` |

> [warn]: Tailwind CSS does not allow you to generate and apply CSS classes
> dynamically, which means you need to explicitly specify the class you want to
> apply. In other words, to use dynamic classes, you need to ensure that they
> are present in the final CSS file.
>
> | Twind                               | Tailwind CSS                                                   |
> | ----------------------------------- | -------------------------------------------------------------- |
> | ``<a class={`link-${color}`}></a>`` | ``<a class={color === 'blue' ?`link-blue`:`link-green`}></a>`` |

## Frequently Asked Questions (FAQ)

### What are the differences between twind and Tailwind CSS?

Twind is a project that tries to enable you to use Tailwind-like styling
capabilities in a single script that can also be used in the browser. The key
difference between the two is that twind generates CSS on the fly on every
request and was shipped to the browser to make newly generated classes by
islands work in Fresh. Overall, this wasn't an ideal setup for building
performant sites.

In contrast to that, Tailwind CSS extracts generates the resulting CSS file
ahead of time, which only happens once per deployment. There is no runtime
component needed, which makes your Fresh project respond faster to requests.

During the Tailwind CSS v2 days twind pushed a lot of great ideas like allowing
any number to be used for classes like `opacity-82` and others, but it hasn't
kept up with recent developments of Tailwind CSS. In fact, twind has been
unmaintained for more than a year by now. We never could get autocompletion with
twind to work either.

### Why did Fresh use twind instead of Tailwind CSS?

When Fresh was originally built, Deno didn't support npm modules or node APIs.
This meant that Tailwind CSS didn't work with Deno. Now, many years later, Deno
does ship with support for both of that and we can use the same npm
`tailwindcss` module as everyone else.


================================================
FILE: docs/1.x/examples/modifying-the-head.md
================================================
---
description: |
  Add components like <title> or <meta> to a <head> tag using Fresh's <Head> component.
---

We can use the `<Head />` component in `$fresh/runtime.ts` to add elements as
children of the `<head>` element. By adding elements as children of Fresh's
`<Head />` tag, these automatically get injected into the `<head>` element of
the web page. Some uses include:

- Setting the document title using `<title>`
- Specifying page metadata using `<meta>`
- Linking to resources like stylesheets using `<link>`
- Including third-party JavaScript code using `<script>`

```tsx routes/index.tsx
import { Head } from "$fresh/runtime.ts";

export default function Home() {
  return (
    <>
      <Head>
        <meta charset="UTF-8" />
        <title>Fresh App</title>
        <meta
          name="description"
          content="This is a brief description of Fresh"
        />
        <link rel="stylesheet" href="styles.css" />
        <script src="script.js"></script>
      </Head>
      <div class="p-4 mx-auto max-w-screen-md">
        <h1>Hello World</h1>
      </div>
    </>
  );
}
```

## Avoiding duplicate tags

You might end up with duplicate tags, when multiple `<Head />` components are
rendered on the same page. This can happen when you render `<Head />` in a route
and another `<Head />` in another component for example.

```tsx routes/page-a.tsx
<Head>
  <meta name="og:title" content="This is a title" />
</Head>;
```

```tsx components/MyTitle.tsx
<Head>
  <meta name="og:title" content="Other title" />
</Head>;
```

To ensure that the tag is not duplicated, Fresh supports setting the `key` prop.
By giving matching elements the same `key` prop, only the last one will be
rendered.

```diff routes/page-a.tsx
  <Head>
-   <meta name="og:title" content="This is a title" />
+   <meta name="og:title" content="This is a title" key="title" />
  </Head>
```

```diff components/MyTitle.tsx
  <Head>
-   <meta name="og:title" content="Other title" />
+   <meta name="og:title" content="Other title" key="title" />
  </Head>
```

The rendered page will only include the `<meta>`-tag with `"Other title"`.

> [info]: The `<title>`-tag is automatically deduplicated, even without a `key`
> prop.


================================================
FILE: docs/1.x/examples/rendering-markdown.md
================================================
---
description: |
  How to render markdown on your Fresh site.
---

What if you want to render some markdown on your site? There are a few
possibilities:

1. the markdown is coming from a remote source
2. the markdown is defined in a string
3. the markdown is on a file

The following file uses
[dynamic routing](https://fresh.deno.dev/docs/getting-started/dynamic-routes) to
handle the three cases. It's assumed this file is called `[slug].tsx`:

```ts routes/[slug].tsx
import { Handlers, PageProps } from "$fresh/server.ts";
import { extract } from "$std/front_matter/yaml.ts";
import { CSS, render } from "$gfm";
import { Head } from "$fresh/runtime.ts";

interface Page {
  markdown: string;
  data: Record<string, unknown>;
}

export const handler: Handlers<Page> = {
  async GET(_req, ctx) {
    let rawMarkdown = "";
    if (ctx.params.slug === "remote") {
      const resp = await fetch(
        `https://raw.githubusercontent.com/denoland/fresh/main/docs/latest/introduction/index.md`,
      );
      if (resp.status !== 200) {
        return ctx.render(undefined);
      }
      rawMarkdown = await resp.text();
    } else if (ctx.params.slug === "string") {
      rawMarkdown = `---
description: test
---

## big text

Look, it's working. _This is in italics._
      
      `;
    } else if (ctx.params.slug === "file") {
      rawMarkdown = await Deno.readTextFile("text.md");
    } else {
      return ctx.render(undefined);
    }
    const { attrs, body } = extract(rawMarkdown);
    return ctx.render({ markdown: body, data: attrs });
  },
};

export default function MarkdownPage({ data }: PageProps<Page | null>) {
  if (!data) {
    return <h1>File not found.</h1>;
  }

  return (
    <>
      <Head>
        <style dangerouslySetInnerHTML={{ __html: CSS }} />
      </Head>
      <main>
        <div>{JSON.stringify(data.data)}</div>
        <div
          class="markdown-body"
          dangerouslySetInnerHTML={{ __html: render(data?.markdown) }}
        />
      </main>
    </>
  );
}
```

The contents of the `text.md` file are the following:

```md text.md
---
description: testFromText
---

# Really Big Text

**bold**
```

You'll also need to import the `Github Flavored Markdown` module:

```sh Terminal
deno add jsr:@deno/gfm
```

Andy has a helpful [post](https://deno.com/blog/build-a-blog-with-fresh) on the
Deno Blog which goes into a slightly more realistic example.


================================================
FILE: docs/1.x/examples/rendering-raw-html.md
================================================
---
description: |
  How to render raw HTML in Fresh.
---

Text content in Fresh is always escaped, whether serverside rendered or rendered
in islands. While this generally desired, it can create issues in certain
situations.

## Warning

The TL;DR is to use Preact's `dangerouslySetInnerHTML`. As the name implies, it
should not be used lightly.

Setting arbitrary HTML can be dangerous. Make sure you trust the source.
Rendering user-supplied HTML to the DOM makes your site vulnerable to cross-
site scripting. The markup must first be sanitizied, or better yet, something
you trust.

## Example: Rendering JSON-LD

Suppose we need to add some microdata markup to a page. The following will
result in **escaped characters, and will not work**:

```tsx components/json-ld.tsx
const json = `
{
  "@context": "http://schema.org",
  "@type": "PostalAddress",
  "streetAddress": "8888 University Drive",
  "addressLocality": "Burnaby",
  "addressRegion": "British Columbia"
}
`;

export default function JsonLd() {
  return <script type="application/ld+json">{json}</script>;
}
```

Instead, we can use `dangerouslySetInnerHTML`:

```tsx components/json-ld.tsx
export default function JsonLd() {
  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: json }}
    />
  );
}
```

## Another example: Code highlighting

Syntax highlighters parse strings into HTML tags, allowing them to be
individually styled with CSS. We can build a simple Preact syntax highlighter
like so:

```tsx components/code.tsx
import Prism from "https://esm.sh/prismjs@1.29.0";

interface Props {
  code: string;
  lang: string;
}

export default function Code({ code, lang }: Props) {
  const parsed = Prism.highlight(code, Prism.languages[lang], lang);

  return (
    <pre data-lang={lang} className={`language-${lang}`}>
      <code
        dangerouslySetInnerHTML={{
          __html: parsed,
        }}
      />
    </pre>
  );
}
```

Of course, we will also have to add some CSS to make this look nice.


================================================
FILE: docs/1.x/examples/setting-the-language.md
================================================
---
description: |
  Set the lang attribute in the <html> tag.
---

When you initialize a project with `deno run -A -r https://fresh.deno.dev`,
you'll end up with a `main.ts` like the following:

```ts main.ts
/// <reference no-default-lib="true" />
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
/// <reference lib="dom.asynciterable" />
/// <reference lib="deno.ns" />

import { start } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";

import twindPlugin from "$fresh/plugins/twind.ts";
import twindConfig from "./twind.config.ts";

await start(manifest, { plugins: [twindPlugin(twindConfig)] });
```

This is a great start if your site is in English, but let's say you want to
change the language, as per the `<html lang=asdf>` tag. Then you'll need to do
something like this:

```ts main.ts
/// <reference no-default-lib="true" />
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
/// <reference lib="dom.asynciterable" />
/// <reference lib="deno.ns" />

import { start } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";

import twindPlugin from "$fresh/plugins/twind.ts";
import twindConfig from "./twind.config.ts";

await start(manifest, {
  plugins: [twindPlugin(twindConfig)],
  render: (ctx, render) => {
    ctx.lang = "de";
    render();
  },
});
```

If you're curious how this works, start by checking out `TemplateOptions` in
`render.ts`.


================================================
FILE: docs/1.x/examples/sharing-state-between-islands.md
================================================
---
description: |
  When you need to have state shared between islands, this page provides a few recipes.
---

All of this content is lifted from this great
[example](https://fresh-with-signals.deno.dev/) by Luca. The source can be found
[here](https://github.com/lucacasonato/fresh-with-signals).

## Multiple Sibling Islands with Independent State

Imagine we have `Counter.tsx` like this:

```tsx islands/Counter.tsx
import { useSignal } from "@preact/signals";
import { Button } from "../components/Button.tsx";

interface CounterProps {
  start: number;
}

// This island is used to display a counter and increment/decrement it. The
// state for the counter is stored locally in this island.
export default function Counter(props: CounterProps) {
  const count = useSignal(props.start);
  return (
    <div class="flex gap-2 items-center w-full">
      <p class="flex-grow-1 font-bold text-xl">{count}</p>
      <Button onClick={() => count.value--}>-1</Button>
      <Button onClick={() => count.value++}>+1</Button>
    </div>
  );
}
```

Note how `useSignal` is within the `Counter` component. Then if we instantiate
some counters like this...

```tsx routes/index.tsx
<Counter start={3} />
<Counter start={4} />
```

they'll keep track of their own independent state. Not much sharing going on
here, yet.

## Multiple Sibling Islands with Shared State

But we can switch things up by looking at a `SynchronizedSlider.tsx` like this:

```tsx islands/SynchronizedSlider.tsx
import { Signal } from "@preact/signals";

interface SliderProps {
  slider: Signal<number>;
}

// This island displays a slider with a value equal to the `slider` signal's
// value. When the slider is moved, the `slider` signal is updated.
export default function SynchronizedSlider(props: SliderProps) {
  return (
    <input
      class="w-full"
      type="range"
      min={1}
      max={100}
      value={props.slider.value}
      onInput={(e) => (props.slider.value = Number(e.currentTarget.value))}
    />
  );
}
```

Now if we were to do the following...

```tsx routes/index.tsx
export default function Home() {
  const sliderSignal = useSignal(50);
  return (
    <div>
      <SynchronizedSlider slider={sliderSignal} />
      <SynchronizedSlider slider={sliderSignal} />
      <SynchronizedSlider slider={sliderSignal} />
    </div>
  );
}
```

they would all use the same value.

## Independent Islands

We can also create a `signal` in a utility file and export it for consumption
across multiple places.

```ts utils/cart.ts
import { signal } from "@preact/signals";

export const cart = signal<string[]>([]);
```

```tsx islands/AddToCart.tsx
import { Button } from "../components/Button.tsx";
import { cart } from "../utils/cart.ts";

interface AddToCartProps {
  product: string;
}

// This island is used to add a product to the cart state.
export default function AddToCart(props: AddToCartProps) {
  return (
    <Button
      onClick={() => (cart.value = [...cart.value, props.product])}
      class="w-full"
    >
      Add{cart.value.includes(props.product) ? " another" : ""} "{props.product}
      " to cart
    </Button>
  );
}
```

```tsx islands/Cart.tsx
import { Button } from "../components/Button.tsx";
import { cart } from "../utils/cart.ts";
import * as icons from "../components/Icons.tsx";

// This island is used to display the cart contents and remove items from it.
export default function Cart() {
  return (
    <h1 class="text-xl flex items-center justify-center">
      Cart
    </h1>

    <ul class="w-full bg-gray-50 mt-2 p-2 rounded-sm min-h-[6.5rem]">
      {cart.value.length === 0 && (
        <li class="text-center my-4">
          <div class="text-gray-400">
            <icons.Cart class="w-8 h-8 inline-block" />
            <div>
              Your cart is empty.
            </div>
          </div>
        </li>
      )}
      {cart.value.map((product, index) => (
        <CartItem product={product} index={index} />
      ))}
    </ul>
  );
}

interface CartItemProps {
  product: string;
  index: number;
}

function CartItem(props: CartItemProps) {
  const remove = () => {
    const newCart = [...cart.value];
    newCart.splice(props.index, 1);
    cart.value = newCart;
  };

  return (
    <li class="flex items-center justify-between gap-1">
      <icons.Lemon class="text-gray-500" />
      <div class="flex-1">
        {props.product}
      </div>
      <Button onClick={remove} aria-label="Remove" class="border-none">
        <icons.X class="inline-block w-4 h-4" />
      </Button>
    </li>
  );
}
```

Now we can add the islands to our site by doing the following:

```tsx routes/cart.tsx
<AddToCart product="Lemon" />
<AddToCart product="Lime" />
<Cart />
```

What happens as a result? The `cart` signal is shared across the two `AddToCart`
islands _and_ the `Cart` island.


================================================
FILE: docs/1.x/examples/using-csp.md
================================================
---
description: |
  Change the source directory to effectively manage your project.
---

As per the
[MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP):

> Content Security Policy (CSP) is an added layer of security that helps to
> detect and mitigate certain types of attacks, including Cross-Site Scripting
> (XSS) and data injection attacks. These attacks are used for everything from
> data theft, to site defacement, to malware distribution.
>
> To enable CSP, you need to configure your web server to return the
> Content-Security-Policy HTTP header. (Sometimes you may see mentions of the
> X-Content-Security-Policy header, but that's an older version and you don't
> need to specify it anymore.)

Fortunately Fresh has built in support for CSP. We don't need to worry about
setting headers ourselves. We just have to configure our routes correctly. Let's
dive into a few examples to see how this works.

Fresh's CSP implementation supports the following

<details>
<summary>directives</summary>

```ts fresh 🍋
export interface ContentSecurityPolicyDirectives {
  // Fetch directives
  /**
   * Defines the valid sources for web workers and nested browsing contexts
   * loaded using elements such as <frame> and <iframe>.
   */
  childSrc?: string[];
  /**
   * Restricts the URLs which can be loaded using script interfaces.
   */
  connectSrc?: string[];
  /**
   * Serves as a fallback for the other fetch directives.
   */
  defaultSrc?: string[];
  /**
   * Specifies valid sources for fonts loaded using @font-face.
   */
  fontSrc?: string[];
  /**
   * Specifies valid sources for nested browsing contexts loading using elements
   * such as <frame> and <iframe>.
   */
  frameSrc?: string[];
  /**
   * Specifies valid sources of images and favicons.
   */
  imgSrc?: string[];
  /**
   * Specifies valid sources of application manifest files.
   */
  manifestSrc?: string[];
  /**
   * Specifies valid sources for loading media using the <audio> , <video> and
   * <track> elements.
   */
  mediaSrc?: string[];
  /**
   * Specifies valid sources for the <object>, <embed>, and <applet> elements.
   */
  objectSrc?: string[];
  /**
   * Specifies valid sources to be prefetched or prerendered.
   */
  prefetchSrc?: string[];
  /**
   * Specifies valid sources for JavaScript.
   */
  scriptSrc?: string[];
  /**
   * Specifies valid sources for JavaScript <script> elements.
   */
  scriptSrcElem?: string[];
  /**
   * Specifies valid sources for JavaScript inline event handlers.
   */
  scriptSrcAttr?: string[];
  /**
   * Specifies valid sources for stylesheets.
   */
  styleSrc?: string[];
  /**
   * Specifies valid sources for stylesheets <style> elements and <link>
   * elements with rel="stylesheet".
   */
  styleSrcElem?: string[];
  /**
   * Specifies valid sources for inline styles applied to individual DOM
   * elements.
   */
  styleSrcAttr?: string[];
  /**
   * Specifies valid sources for Worker, SharedWorker, or ServiceWorker scripts.
   */
  workerSrc?: string[];

  // Document directives
  /**
   * Restricts the URLs which can be used in a document's <base> element.
   */
  baseUri?: string[];
  /**
   * Enables a sandbox for the requested resource similar to the <iframe>
   * sandbox attribute.
   */
  sandbox?: string[];

  // Navigation directives
  /**
   * Restricts the URLs which can be used as the target of a form submissions
   * from a given context.
   */
  formAction?: string[];
  /**
   * Specifies valid parents that may embed a page using <frame>, <iframe>,
   * <object>, <embed>, or <applet>.
   */
  frameAncestors?: string[];
  /**
   * Restricts the URLs to which a document can initiate navigation by any
   * means, including <form> (if form-action is not specified), <a>,
   * window.location, window.open, etc.
   */
  navigateTo?: string[];

  /**
   * The URI to report CSP violations to.
   */
  reportUri?: string;
}
```

</details>

For our examples, we'll just be focused on `styleSrc`, but the technique can be
applied to any of the directives.

We'll start off by having an example stylesheet defined like this:

```css static/example.css
h1 {
  font-size: 25px;
  font-weight: normal;
  margin-top: 5px;
  margin-left: 25px;
}
```

## No CSP

To kick things off, we'll create the following control route which doesn't do
anything with CSP. We include a stylesheet to confirm that our sheet correctly
styles the response.

```tsx routes/noCSP.tsx
import { RouteContext } from "$fresh/server.ts";

export default function Home(req: Request, ctx: RouteContext) {
  return (
    <>
      <h1>This page doesn't use CSP at all. Styles will be applied.</h1>
      <link rel="stylesheet" type="text/css" href="example.css" />
    </>
  );
}
```

We can hit `http://localhost:8000/noCSP` and we should see the following:

```txt Response body
This page doesn't use CSP at all. Styles will be applied.
```

## Incorrect CSP

Let's invoke the `useCSP` hook in our response to try to secure our page. Watch
closely, we're using the wrong URL! This will cause the browser to reject the
stylesheet, due to the header that Fresh produces. We get a `(blocked:csp)`
status when the browser tries to request this resource.

```tsx routes/incorrectCSP.tsx
import { RouteConfig, RouteContext } from "$fresh/server.ts";
import { useCSP } from "$fresh/runtime.ts";

export default function Home(req: Request, ctx: RouteContext) {
  useCSP((csp) => {
    if (!csp.directives.styleSrc) {
      csp.directives.styleSrc = [];
    }
    csp.directives.styleSrc.push("http://www.example.com");
  });
  return (
    <>
      <h1>This page violates our configured CSP. Styles won't be applied.</h1>
      <link rel="stylesheet" type="text/css" href="example.css" />
    </>
  );
}

export const config: RouteConfig = {
  csp: true,
};
```

We can hit `http://localhost:8000/incorrectCSP` and we should see the following:

```txt Response body
This page violates our configured CSP. Styles won't be applied.
```

## Correct CSP

Let's fix our simple mistake and use the correct URL. Everything is working
correctly here.

```tsx routes/correctCSP.tsx
import { RouteConfig, RouteContext } from "$fresh/server.ts";
import { useCSP } from "$fresh/runtime.ts";

export default function Home(req: Request, ctx: RouteContext) {
  useCSP((csp) => {
    if (!csp.directives.styleSrc) {
      csp.directives.styleSrc = [];
    }
    csp.directives.styleSrc.push("http://localhost:8000/example.css");
  });
  return (
    <>
      <h1>This page adheres to our configured CSP. Styles will be applied.</h1>
      <link rel="stylesheet" type="text/css" href="example.css" />
    </>
  );
}

export const config: RouteConfig = {
  csp: true,
};
```

We can hit `http://localhost:8000/correctCSP` and we should see the following:

```txt Response body
This page adheres to our configured CSP. Styles will be applied.
```

## No Route Config

What happens if we forget to use a `RouteConfig` in our route?

```tsx routes/cspNoRouteConfig.tsx
import { RouteContext } from "$fresh/server.ts";
import { useCSP } from "$fresh/runtime.ts";

export default function Home(req: Request, ctx: RouteContext) {
  useCSP((csp) => {
    if (!csp.directives.styleSrc) {
      csp.directives.styleSrc = [];
    }
    csp.directives.styleSrc.push("http://www.example.com");
  });
  return (
    <>
      <h1>
        This page violates our configured CSP. But we don't have a{" "}
        <code>RouteConfig</code>{" "}
        enabled, so Fresh doesn't know to use the CSP. Styles will be applied.
      </h1>
      <link rel="stylesheet" type="text/css" href="example.css" />
    </>
  );
}
```

We can hit `http://localhost:8000/cspNoRouteConfig` and we should see the
following:

```txt Response body
This page violates our configured CSP. But we don't have a RouteConfig enabled, so Fresh doesn't know to use the CSP. Styles will be applied.
```

## Reporting

Let's touch on the reporting aspect of CSP. CSP (and Fresh's framework) support
a `reportOnly` flag and a `reportUri` endpoint. This is a destination that
should be able to receive `POST` requests. If the `reportOnly` flag is enabled,
then the browser will ignore the CSP headers and log any issues to the
`reportUri` destination.

```tsx routes/incorrectCSPwithReport.tsx
import { RouteConfig, RouteContext } from "$fresh/server.ts";
import { useCSP } from "$fresh/runtime.ts";

export default function Home(req: Request, ctx: RouteContext) {
  useCSP((csp) => {
    csp.reportOnly = true;
    if (!csp.directives.styleSrc) {
      csp.directives.styleSrc = [];
    }
    csp.directives.reportUri = "http://localhost:8000/reportHandler";
    csp.directives.styleSrc.push("http://www.example.com");
  });
  return (
    <>
      <h1>
        This page violates our configured CSP. But we're using "reportOnly".
        Styles will be applied.
      </h1>
      <link rel="stylesheet" type="text/css" href="example.css" />
    </>
  );
}

export const config: RouteConfig = {
  csp: true,
};
```

```ts routes/reportHandler.ts
import { FreshContext } from "$fresh/server.ts";

export const handler = {
  async POST(req: Request, _ctx: FreshContext) {
    const body = await req.json();
    const report = JSON.stringify(body, null, 2);

    await Deno.writeTextFile("./csp-reports.txt", report + "\n", {
      append: true,
    });
    return new Response(null, { status: 200 });
  },
};
```

We can hit `http://localhost:8000/incorrectCSPwithReport` and we should see the
following:

```txt Response body
This page violates our configured CSP. But we're using "reportOnly". Styles will be applied.
```

We can then check our server and we'll see that `csp-reports.txt` has an entry
like this:

```json csp-reports.txt
{
  "csp-report": {
    "document-uri": "http://localhost:8000/incorrectCSPwithReport",
    "referrer": "http://localhost:8000/incorrectCSPwithReport",
    "violated-directive": "style-src-elem",
    "effective-directive": "style-src-elem",
    "original-policy": "default-src 'none'; style-src 'unsafe-inline' http://www.example.com; report-uri http://localhost:8000/reportHandler; script-src 'nonce-0f2d8259315d40479e8c21979128ac0d'; connect-src 'self'",
    "disposition": "report",
    "blocked-uri": "http://localhost:8000/example.css",
    "line-number": 37,
    "source-file": "http://localhost:8000/incorrectCSPwithReport",
    "status-code": 200,
    "script-sample": ""
  }
}
```


================================================
FILE: docs/1.x/examples/using-fresh-canary-version.md
================================================
---
description: |
  For cases where the latest release doesn't fit your needs.
---

Pretend you have a use case where you need to modify your project to use a
canary version of Fresh. Or you want to use a slightly different initialization
script. This page has you covered.

## Canary Fresh in `deno.json`

### Latest alpha version

The easiest way to use Fresh 2 canary is with the update command:

```sh Terminal
deno run -A -r jsr:@fresh/update@2.0.0-alpha.35 .
```

This will automatically update your `deno.json` to use the specified canary
version.

### Specific commit

If you need a particular commit (for testing specific fixes or features):

```diff deno.json
   "tasks": {
     "update": "deno run -A -r jsr:@fresh/update ."
   },
   "imports": {
-    "$fresh/": "jsr:@fresh/core@^2.0.0",
+    "$fresh/": "https://raw.githubusercontent.com/denoland/fresh/your-commit-hash/",
     "preact": "npm:preact@^10.26.9",
     "@preact/signals": "npm:@preact/signals@^2.2.0"
   }
```

Replace `your-commit-hash` with your desired commit hash.

### Forked Fresh

For testing your own fork or PR:

```diff deno.json
   "tasks": {
     "update": "deno run -A -r jsr:@fresh/update ."
   },
   "imports": {
-    "$fresh/": "https://deno.land/x/fresh@1.7.3/",
+    "$fresh/": "https://raw.githubusercontent.com/your-username/fresh/your-branch/",
     "preact": "https://esm.sh/preact@10.26.9",
     "preact/": "https://esm.sh/preact@10.22.0/",
   }
```

## Creating a new project

### Using JSR

```sh Terminal
deno run -A -r jsr:@fresh/init@2.0.0-alpha.35
```

### From local source

If you're developing Fresh itself:

```sh Terminal
deno run -A -r ./init/src/init.ts
```

### Recommended reading

- [Fresh v2 blog](https://deno.com/blog/fresh-2)
- [Migration guide](../../migration-guide.md)


================================================
FILE: docs/1.x/examples/using-twind-v1.md
================================================
---
description: |
  With a few tweaks one can use twind v1
---

When you initialize a project with `deno run -A -r https://fresh.deno.dev`,
you'll end up with a `main.ts` like the following:

```ts main.ts
/// <reference no-default-lib="true" />
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
/// <reference lib="dom.asynciterable" />
/// <reference lib="deno.ns" />

import "$std/dotenv/load.ts";

import { start } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";
import config from "./fresh.config.ts";

await start(manifest, config);
```

And the Fresh config is like this:

```ts fresh.config.ts
import { defineConfig } from "$fresh/server.ts";
import twindPlugin from "$fresh/plugins/twind.ts";
import twindConfig from "./twind.config.ts";

export default defineConfig({
  plugins: [twindPlugin(twindConfig)],
});
```

Let's bump that up to v1:

```diff fresh.config.ts
 import { defineConfig } from "$fresh/server.ts";
-import twindPlugin from "$fresh/plugins/twind.ts";
+import twindPlugin from "$fresh/plugins/twindv1.ts";
 import twindConfig from "./twind.config.ts";

 export default defineConfig({
```

The twind config object has changed significantly in v1, so we must also change
`twind.config.ts`. A good base looks like this (just replace whatever is there
with this):

```ts twind.config.ts
import { defineConfig, Preset } from "https://esm.sh/@twind/core@1.1.3";
import presetTailwind from "https://esm.sh/@twind/preset-tailwind@1.1.4";
import presetAutoprefix from "https://esm.sh/@twind/preset-autoprefix@1.0.7";

export default {
  ...defineConfig({
    presets: [presetTailwind() as Preset, presetAutoprefix()],
  }),
  selfURL: import.meta.url,
};
```

(Note: the `as Preset` cast is required to fix a typing issue with twind.)

To see what other presets exist, you can go to the
[twind docs](https://twind.style/presets).


================================================
FILE: docs/1.x/examples/writing-tests.md
================================================
---
description: |
  You can write HTTP tests for your Fresh project by creating an application handler.
---

You can write tests for your Fresh project by creating an application handler
through
[`createHandler()`](https://deno.land/x/fresh/server.ts?doc=&s=createHandler).

## 1. Create your routes

```tsx routes/index.tsx
import { Handlers } from "$fresh/server.ts";

export const handler: Handlers = {
  async POST(req) {
    const form = await req.formData();

    // Processing something

    return new Response(null, {
      status: 303,
      headers: { location: "/" },
    });
  },
};

export default function HomePage() {
  return <div>Hello Deno!</div>;
}
```

```tsx routes/foo.tsx
export default function FooPage() {
  return <div>Hello Foo!</div>;
}
```

## 2. Write your tests

```ts tests/main_test.ts
import { createHandler, ServeHandlerInfo } from "$fresh/server.ts";
import manifest from "../fresh.gen.ts";
import config from "../fresh.config.ts";
import { assert, assertEquals } from "$std/testing/asserts.ts";

const CONN_INFO: ServeHandlerInfo = {
  remoteAddr: { hostname: "127.0.0.1", port: 53496, transport: "tcp" },
};

Deno.test("HTTP assert test.", async (t) => {
  const handler = await createHandler(manifest, config);

  await t.step("#1 GET /", async () => {
    const resp = await handler(new Request("http://127.0.0.1/"), CONN_INFO);
    assertEquals(resp.status, 200);
  });

  await t.step("#2 POST /", async () => {
    const formData = new FormData();
    formData.append("text", "Deno!");
    const req = new Request("http://127.0.0.1/", {
      method: "POST",
      body: formData,
    });
    const resp = await handler(req, CONN_INFO);
    assertEquals(resp.status, 303);
  });

  await t.step("#3 GET /foo", async () => {
    const resp = await handler(new Request("http://127.0.0.1/foo"), CONN_INFO);
    const text = await resp.text();
    assert(text.includes("<div>Hello Foo!</div>"));
  });
});
```

## 3. Run the tests

```sh Terminal
$ deno test --allow-read --allow-env --allow-net
running 1 test from ./tests/main_test.ts
HTTP assert test. ...
  #1 GET / ... ok (31ms)
  #2 POST / ... ok (35ms)
  #3 GET /foo ... ok (12ms)
HTTP assert test. ... ok (118ms)

ok | 1 passed (3 steps) | 0 failed (236ms)
```

## createHandler in detail

This function is typed as follows:

```ts fresh 🍋
export async function createHandler(
  manifest: Manifest,
  config: FreshConfig = {},
): Promise<
  (req: Request, connInfo?: ServeHandlerInfo) => Promise<Response>
```

When you're using it, you'll likely be importing the manifest from your project.
You can of course import the config (`fresh.config.ts`) as well, but you're also
free to provide your own bag of options.
[`FreshConfig`](https://deno.land/x/fresh/server.ts?s=FreshConfig) is declared
as follows:

```ts fresh 🍋
export interface FreshConfig {
  build?: {
    outDir?: string;
    target?: string | string[];
  };
  render?: RenderFunction;
  plugins?: Plugin[];
  staticDir?: string;
  router?: RouterOptions;
  server?: Partial<Deno.ServeTlsOptions>;
}
```

For more on how these work, see the page about
[server configuration](/docs/1.x/concepts/server-configuration).


================================================
FILE: docs/1.x/getting-started/adding-interactivity.md
================================================
---
description: |
  Add JavaScript based interactivity to your project without sacrificing user
  experience, by using Fresh's powerful islands system.
---

Up to now none of the pages in the demo project have contained any client side
JavaScript. This is great for resiliency and performance, but it can also limit
the possibilities of interactivity. In many current generation web frameworks,
you get the choice of shipping no JavaScript to the client or shipping a
renderer for the entire page.

This is not very flexible, especially considering that most pages will only have
small pieces of content that require interactivity. For example, an otherwise
static page might need a little bit of JavaScript to power an image carousel or
"buy now" button. This model is often called
[islands architecture][islands-architecture]. This refers to a page having
little "islands" of interactivity, in a sea of otherwise static content.

Fresh embraces this model. All pages are rendered server side, but you can
create "island components" that are _also_ rendered client side. To do this,
Fresh projects have a special `islands/` folder. The modules in this folder each
encapsulate a single island component. The name of the module should be the
[pascal case][pascal-case] or [kebab case][kebab-case] name of the island
component. For example a counter component would be defined in the file
`islands/Counter.tsx`. A buy now button could be defined in the file
`islands/buy-now-button.tsx`.

Here is an example of an island component that counts down to a specific time.

```tsx islands/Countdown.tsx
import { useSignal } from "@preact/signals";
import { useEffect } from "preact/hooks";

const timeFmt = new Intl.RelativeTimeFormat("en-US");

// The target date is passed as a string instead of as a `Date`, because the
// props to island components need to be JSON (de)serializable.
export default function Countdown(props: { target: string }) {
  const target = new Date(props.target);
  const now = useSignal(new Date());

  // Set up an interval to update the `now` date every second with the current
  // date as long as the component is mounted.
  useEffect(() => {
    const timer = setInterval(() => {
      if (now.value > target) {
        clearInterval(timer);
      }
      now.value = new Date();
    }, 1000);
    return () => clearInterval(timer);
  }, [props.target]);

  const secondsLeft = Math.floor(
    (target.getTime() - now.value.getTime()) / 1000,
  );

  // If the target date has passed, we stop counting down.
  if (secondsLeft <= 0) {
    return <span>🎉</span>;
  }

  // Otherwise, we format the remaining time using `Intl.RelativeTimeFormat` and
  // render it.
  return <span>{timeFmt.format(secondsLeft, "seconds")}</span>;
}
```

To include this in a page component, one can just use the component normally.
Fresh will take care of automatically mounting the island component on the
client with the correct props:

```tsx routes/countdown.tsx
import Countdown from "../islands/Countdown.tsx";

export default function Page() {
  const date = new Date();
  date.setHours(date.getHours() + 1);
  return (
    <p>
      The big event is happening <Countdown target={date.toISOString()} />.
    </p>
  );
}
```

The page that is rendered on the client now has an interactive countdown.

[islands-architecture]: https://jasonformat.com/islands-architecture
[pascal-case]: https://en.wiktionary.org/wiki/Pascal_case
[kebab-case]: https://en.wiktionary.org/wiki/kebab_case


================================================
FILE: docs/1.x/getting-started/create-a-project.md
================================================
---
description: |
  Create a new Fresh project by running the Fresh project creation tool. This
  scaffolds out the various files and folders a Fresh project needs.
---

New Fresh projects can be created by using the Fresh project creation tool. It
will scaffold out a new project with some example files to get you started.

To create a new project, run:

```sh Terminal
deno run -A -r https://fresh.deno.dev
cd fresh-project
deno task start
```

This will scaffold out the new project, then switch into the newly created
directory, and then start the development server.

This will create a directory containing some files and directories. There are 4
files that are strictly necessary to run a Fresh project:

- **`dev.ts`**: This is the development entry point for your project. This is
  the file that you run to start your project. This file doesn't need to be
  called `dev.ts`, but this is the convention.
- **`main.ts`**: This is the production entry point for your project. It is the
  file that you link to Deno Deploy. This file doesn't actually need to be
  `main.ts`, but this is the convention.
- **`fresh.gen.ts`**: This is the manifest file that contains information about
  your routes and islands. This file is automatically generated in development
  based on your `routes/` and `islands/` folders.

A **`deno.json`** file is also created in the project directory. This file does
two things:

- It defines the "imports" field. This is an [import map][import-map] that is
  used to manage dependencies for the project. This allows for easy importing
  and updating of dependencies.
- It registers a "start" [task][task-runner] to run the project without having
  to type a long `deno run` command.

Two important folders are also created that contain your routes and islands
respectively:

- **`routes/`**: This folder contains all of the routes in your project. The
  name of each file in this folder corresponds to the path where that page will
  be accessed. Code inside of this folder is never directly shipped to the
  client. You'll learn more about how routes work in the next section.
- **`islands/`**: This folder contains all of the interactive islands in your
  project. The name of each file corresponds to the name of the island defined
  in that file. Code inside of this folder can be run from both client and
  server. You'll learn more about islands later in this chapter.

Finally a **`static/`** folder is created that contains static files that are
automatically served "as is". [Learn more about static files][static-files].

[import-map]: https://docs.deno.com/runtime/fundamentals/modules
[task-runner]: https://docs.deno.com/runtime/reference/cli/task
[static-files]: ../concepts/static-files


================================================
FILE: docs/1.x/getting-started/create-a-route.md
================================================
---
description: |
  Create a new route to a Fresh project by creating a new file in the `routes/`
  folder.
---

After getting the project running locally, the next step is to add a new route
to the project. Routes encapsulate the logic for handling requests to a
particular path in your project. They can be used to handle API requests or
render HTML pages. For now we are going to do the latter.

Routes are defined as files in the `routes` directory. The file name of the
module is important: it is used to determine the path that the route will
handle. For example, if the file name is `index.js`, the route will handle
requests to `/`. If the file name is `about.js`, the route will handle requests
to `/about`. If the file name is `contact.js` and is placed inside of the
`routes/about/` folder, the route will handle requests to `/about/contact`. This
concept is called _File-system routing_. You can learn more about it on the
[_Concepts: Routing_][concepts-routing] page.

Route files that render HTML are JavaScript or TypeScript modules that export a
JSX component as their default export. This component will be rendered for every
request to the route's path. The component receives a few properties that can be
used to customize the rendered output, such as the current route, the url of the
request, state set by middleware, and handler data (more on the last two later).

In the demo project we'll create a route to handle the `/about` page. To do
this, one needs to create a new `routes/about.tsx` file. In this file, we can
declare a component that should be rendered every time a user visits the page.
This is done with JSX.

> [info]: To learn more about JSX, you can read [this article][jsx] in the React
> documentation. Beware that Fresh does not use React, but rather
> [Preact][preact], a lighter weight virtual dom library that works similar to
> React.

```tsx routes/about.tsx
export default function AboutPage() {
  return (
    <main>
      <h1>About</h1>
      <p>This is the about page.</p>
    </main>
  );
}
```

The new page will be visible at `http://localhost:8000/about`.

<!-- You can find more in depth information about routes on the
[_Concepts: Routes_][concepts-routes] documentation page. The following
pages in the _Getting Started_ guide will also explain more features of routes. -->

[concepts-routing]: /docs/1.x/concepts/routing
[jsx]: https://react.dev/learn/writing-markup-with-jsx
[preact]: https://preactjs.com/

<!-- [concepts-routes]: /docs/1.x/concepts/routes -->


================================================
FILE: docs/1.x/getting-started/custom-handlers.md
================================================
---
description: |
  Add custom handlers to a route to customize HTTP headers, implement API
  routes, do data fetching for a rendered page, or handle form submissions.
---

Routes actually consist of two parts: handlers, and the page component. Up to
now, only the page component has been discussed in this chapter.

Handlers are functions in the form of `Request => Response` or
`Request => Promise<Response>` that are called when a request is made to a
particular route. There can be one handler that covers all HTTP methods or one
handler per method.

The handler has access to the `Request` object that backs the request to the
route and must return a `Response` object. The response object can either be
created manually (for example a JSON response for an API route), or it can be
created by rendering the page component. By default, all routes that don't
define a custom handler use a default handler that just renders the page
component.

To define a handler in a route module, one must export it as a named export with
the name `handler`. Handlers can have two forms: a plain function (catchall for
all HTTP methods) or a plain object where each property is a function named by
the HTTP method it handles.

Here is an example of a custom `GET` handler that renders the page component and
then adds a custom header to the response before returning it:

```tsx routes/about.tsx
import { Handlers } from "$fresh/server.ts";

export const handler: Handlers = {
  async GET(_req, ctx) {
    const resp = await ctx.render();
    resp.headers.set("X-Custom-Header", "Hello");
    return resp;
  },
};

export default function AboutPage() {
  return (
    <main>
      <h1>About</h1>
      <p>This is the about page.</p>
    </main>
  );
}
```

Note that handlers do not need to call `ctx.render()`. This feature can be used
to create API routes. Here is an API route that returns a random UUID as a JSON
response:

```ts routes/api/random-uuid.ts
import { Handlers } from "$fresh/server.ts";

export const handler: Handlers = {
  GET(_req) {
    const uuid = crypto.randomUUID();
    return new Response(JSON.stringify(uuid), {
      headers: { "Content-Type": "application/json" },
    });
  },
};
```

Handlers can do much more, including fetching data from a database or external
API and passing it to their route.


================================================
FILE: docs/1.x/getting-started/deploy-to-production.md
================================================
---
description: |
  Deploy a Fresh application to Deno Deploy in seconds, making it available on
  the edge globally - resulting in fantastic user latency worldwide.
---

As a final step in the getting started guide, we'll deploy the demo site to the
public internet using [Deno Deploy][deno-deploy]. Deno Deploy is a globally
distributed edge runtime built by the Deno company that allows developers to
quickly and painlessly deploy web applications to the internet. Deno Deploy has
edge nodes all over the world that serve traffic. Because of this, users
worldwide have fantastic latency because their traffic is served from a server
that is physically close to them.

To deploy to Deno Deploy, we'll make use of the GitHub integration. To use this
the code needs to be pushed to a repository on GitHub. Once this has been done,
one must go to the [Deno Deploy dashboard][deno-deploy-dashboard] and create a
new project.

Click on the "New Project" button and select the GitHub repository that contains
the Fresh project. Select the "Fresh" framework preset, and click on "Advanced
options". Enter `deno task build` in the "Build command" field. Press "Create
project".

The project will now deploy to Deno Deploy. After this is done, the project will
be available at https://$PROJECT_NAME.deno.dev.

Every time the code in the GitHub repository is updated, it will be deployed
either as a preview or production deployment. Production deployments are only
created for changes to the default/production branch (often `main`).

[deno-deploy]: https://deno.com/deploy
[deno-deploy-dashboard]: https://dash.deno.com/projects


================================================
FILE: docs/1.x/getting-started/dynamic-routes.md
================================================
---
description: |
  Create a dynamic route in Fresh by adding a dynamic segment to the route name
  in the routes' file name on disk: `/greet/[name].tsx`.
---

The `/about` route created on the last page is pretty static. It does not matter
what query or path parameters are passed to the route, it will always render the
same page. Let's create a `/greet/:name` that will render a page with a greeting
that contains the name passed in the path.

Before diving in, a quick refresher on "dynamic" routes. Dynamic routes don't
just match a single static path, but rather a whole bunch of different paths
based on a pattern. For example, the `/greet/:name` route will match the paths
`/greet/Luca` and `/greet/John`, but not `/greet/Luca/John`.

Fresh supports dynamic routes out of the box through file system routing. To
make any path segment dynamic, just put square brackets around that segment in
the file name. For example the `/greet/:name` route maps to the file name
`routes/greet/[name].tsx`.

Just like the static `/about` route, the dynamic `/greet/:name` route will
render a page. The module must once again expose a component as a default
export. This time the component will receive the matched path segment properties
as arguments in its `props` object though.

```tsx routes/greet/[name].tsx
import { PageProps } from "$fresh/server.ts";

export default function GreetPage(props: PageProps) {
  const { name } = props.params;
  return (
    <main>
      <p>Greetings to you, {name}!</p>
    </main>
  );
}
```

The `PageProps` interface actually contains a bunch of useful properties that
can be used to customize the rendered output. Next to the matched url pattern
parameters, the raw `url`, and the `route` name can also be found in here.

Navigating to `http://localhost:8000/greet/Luca` will now render a page showing
"Greetings to you, Luca!".

The [_Concepts: Routing_][concepts-routing] page has more information about
dynamic routes, especially about how to create more advanced dynamic routes.

[concepts-routing]: /docs/1.x/concepts/routing


================================================
FILE: docs/1.x/getting-started/form-submissions.md
================================================
---
description: |
  Robustly handle user inputs using HTML `<form>` elements client side, and form
  submission handlers server side.
---

Forms are a common mechanism for letting users interact with applications. In
the last few years it has become more and more common for web applications to
move form submission entirely to the client. This can have useful properties for
interactivity, but it is much worse for resiliency and user experience as a
whole. Browsers have great built in systems for form submission, revolving
around the HTML `<form>` element.

Fresh builds the core of its form submission infrastructure around the native
`<form>` element. This page explains how to use `<form>` in Fresh, and the next
chapter explains how to progressively enhance your forms with client side
JavaScript to make them more interactive.

The way forms work in the browser, is that they perform an HTML navigation
action when the user submits the form. In most cases this means that when the
form is submitted, a `GET` or `POST` request is sent to the server with the form
data, which then responds with a new page to render.

Fresh can handle both `GET` and `POST` requests through the
[custom handlers][custom-handlers] feature of routes. The handlers can perform
any necessary processing on the form data, and then pass data to the
`ctx.render()` call to render a new page.

Here is an example implementing a search form that filters an array of names
server side:

```tsx routes/search.tsx
import { Handlers, PageProps } from "$fresh/server.ts";

const NAMES = ["Alice", "Bob", "Charlie", "Dave", "Eve", "Frank"];

interface Data {
  results: string[];
  query: string;
}

export const handler: Handlers<Data> = {
  GET(req, ctx) {
    const url = new URL(req.url);
    const query = url.searchParams.get("q") || "";
    const results = NAMES.filter((name) => name.includes(query));
    return ctx.render({ results, query });
  },
};

export default function Page({ data }: PageProps<Data>) {
  const { results, query } = data;
  return (
    <div>
      <form>
        <input type="text" name="q" value={query} class="border p-1" />
        <button type="submit" class="ml-1 px-2 py-1 bg-gray-100 border">
          Search
        </button>
      </form>
      <ul>
        {results.map((name) => <li key={name}>{name}</li>)}
      </ul>
    </div>
  );
}
```

When the user submits the form, the browser will navigate to `/search` with the
query set as the `q` query parameter in the URL. The `GET` handler will then
filter the names array based on the query, and pass it to the page component for
rendering.

[Learn more about using forms in Fresh][concepts-forms].

<!-- TODO(lucacasonato): link to todo app example when that is built again -->

[custom-handlers]: /docs/1.x/getting-started/custom-handlers
[concepts-forms]: /docs/1.x/concepts/forms


================================================
FILE: docs/1.x/getting-started/index.md
================================================
---
description: |
  In this chapter of the Fresh documentation, you'll be introduced to the
  framework. Create a new project, run it locally, edit and create pages, fetch
  data, handle user interactions, and deploy it.
---

In this chapter of the Fresh documentation, you'll be introduced to the
framework. You'll learn how to create a new project, run it locally, edit and
create pages, fetch data, handle user interactions, and how to then deploy the
project to [Deno Deploy](https://deno.com/deploy).

The documentation assumes you have the latest version
[Deno](https://docs.deno.com/runtime/#install-deno) installed on your system and
set up your
[Editor to work with Deno](https://docs.deno.com/runtime/getting_started/setup_your_environment/).


================================================
FILE: docs/1.x/getting-started/running-locally.md
================================================
---
description: |
  To start a Fresh project, just run `deno task start`. This will start the
  project with default permission flags, in watch mode.
---

The next step after scaffolding out a new project, is to actually start it. To
do this you can just `deno task start`. Environment variables will be
automatically read from `.env`.

```sh Terminal
$ deno task start
Watcher Process started.
 🍋 Fresh ready
     Local: http://localhost:8000
```

If you want to start manually without Deno task, `deno run` the `main.ts` with
the appropriate flags. You will need to provide permission flags for:

- **`--allow-net`**: This is required to start the HTTP server.
- **`--allow-read`**: This is required to read (static) files from disk.
- **`--allow-env`**: This is required to read environment variables that can be
  used to configure your project.
- **`--allow-run`**: This is required to shell out to `deno` and `esbuild` under
  the hood during development to do type stripping. In production this is done
  using a WebAssembly binary.

For development, you also want to run with the [`--watch` flag][--watch], so the
Fresh server will automatically reload whenever you make a change to your code.
By default `--watch` only watches over files in your module graph. Some project
files like static files are not part of the module graph, but you probably want
to restart/reload whenever you make a change to them too. This can be done by
passing the extra folder as an argument: `--watch=static/`. You should also add
`routes/` to the watch list, so that the server restarts automatically whenever
you add a new route.

If you want to change the port or host, modify the config bag of the `start()`
call in `main.ts` to include an explicit port number:

```ts main.ts
await start(manifest, { server: { port: 3000 } });
```

You can also change the port by setting the `PORT` environment variable:

```sh Terminal
$ PORT=3000 deno task start
```

Combining all of this we get the following `deno run` command:

```sh Terminal
$ deno run --allow-net --allow-read --allow-env --allow-run --watch=static/,routes/ main.ts
Watcher Process started.
 🍋 Fresh ready
     Local: http://localhost:3000
```

If you now visit http://localhost:3000, you can see the running project. Try
change some of the text in `routes/index.tsx` and see how the page updates
automatically when you save the file.

[--watch]: https://docs.deno.com/runtime/getting_started/command_line_interface/#watch-mode


================================================
FILE: docs/1.x/integrations/index.md
================================================
---
description: |
  V
Download .txt
gitextract__i6wh6to/

├── .gitattributes
├── .github/
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       ├── deploy.yml
│       ├── post_publish.yml
│       └── publish.yml
├── .gitignore
├── .vscode/
│   ├── extensions.json
│   ├── settings.json
│   └── tailwind.json
├── LICENSE
├── README.md
├── _typos.toml
├── deno.json
├── docs/
│   ├── 1.x/
│   │   ├── concepts/
│   │   │   ├── ahead-of-time-builds.md
│   │   │   ├── app-wrapper.md
│   │   │   ├── architecture.md
│   │   │   ├── data-fetching.md
│   │   │   ├── deployment.md
│   │   │   ├── error-pages.md
│   │   │   ├── forms.md
│   │   │   ├── index.md
│   │   │   ├── islands.md
│   │   │   ├── layouts.md
│   │   │   ├── middleware.md
│   │   │   ├── partials.md
│   │   │   ├── plugins.md
│   │   │   ├── routes.md
│   │   │   ├── routing.md
│   │   │   ├── server-components.md
│   │   │   ├── server-configuration.md
│   │   │   ├── static-files.md
│   │   │   └── updating.md
│   │   ├── examples/
│   │   │   ├── active-links.md
│   │   │   ├── authentication-with-supabase.md
│   │   │   ├── changing-the-src-dir.md
│   │   │   ├── client-side-components-and-libraries.md
│   │   │   ├── creating-a-crud-api.md
│   │   │   ├── dealing-with-cors.md
│   │   │   ├── handling-complex-routes.md
│   │   │   ├── index.md
│   │   │   ├── init-the-server.md
│   │   │   ├── migrating-to-tailwind.md
│   │   │   ├── modifying-the-head.md
│   │   │   ├── rendering-markdown.md
│   │   │   ├── rendering-raw-html.md
│   │   │   ├── setting-the-language.md
│   │   │   ├── sharing-state-between-islands.md
│   │   │   ├── using-csp.md
│   │   │   ├── using-fresh-canary-version.md
│   │   │   ├── using-twind-v1.md
│   │   │   └── writing-tests.md
│   │   ├── getting-started/
│   │   │   ├── adding-interactivity.md
│   │   │   ├── create-a-project.md
│   │   │   ├── create-a-route.md
│   │   │   ├── custom-handlers.md
│   │   │   ├── deploy-to-production.md
│   │   │   ├── dynamic-routes.md
│   │   │   ├── form-submissions.md
│   │   │   ├── index.md
│   │   │   └── running-locally.md
│   │   ├── integrations/
│   │   │   └── index.md
│   │   └── introduction/
│   │       └── index.md
│   ├── canary/
│   │   └── the-canary-version/
│   │       └── index.md
│   ├── latest/
│   │   ├── advanced/
│   │   │   ├── app-wrapper.md
│   │   │   ├── builder.md
│   │   │   ├── define.md
│   │   │   ├── environment-variables.md
│   │   │   ├── error-handling.md
│   │   │   ├── forms.md
│   │   │   ├── head.md
│   │   │   ├── index.md
│   │   │   ├── layouts.md
│   │   │   ├── partials.md
│   │   │   ├── troubleshooting.md
│   │   │   └── vite.md
│   │   ├── concepts/
│   │   │   ├── app.md
│   │   │   ├── context.md
│   │   │   ├── file-routing.md
│   │   │   ├── index.md
│   │   │   ├── islands.md
│   │   │   ├── layouts.md
│   │   │   ├── middleware.md
│   │   │   ├── routing.md
│   │   │   └── static-files.md
│   │   ├── deployment/
│   │   │   ├── cloudflare-workers.md
│   │   │   ├── deno-compile.md
│   │   │   ├── deno-deploy.md
│   │   │   ├── docker.md
│   │   │   └── index.md
│   │   ├── examples/
│   │   │   ├── active-links.md
│   │   │   ├── daisyui.md
│   │   │   ├── markdown.md
│   │   │   ├── migration-guide.md
│   │   │   ├── rendering-raw-html.md
│   │   │   └── sharing-state-between-islands.md
│   │   ├── getting-started/
│   │   │   └── index.md
│   │   ├── introduction/
│   │   │   └── index.md
│   │   ├── plugins/
│   │   │   ├── cors.md
│   │   │   ├── csp.md
│   │   │   ├── csrf.md
│   │   │   ├── index.md
│   │   │   └── trailing-slashes.md
│   │   └── testing/
│   │       └── index.md
│   └── toc.ts
├── packages/
│   ├── build-id/
│   │   ├── README.md
│   │   ├── deno.json
│   │   └── mod.ts
│   ├── examples/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── deno.json
│   │   └── src/
│   │       ├── app1.tsx
│   │       ├── app2.tsx
│   │       ├── island.tsx
│   │       └── shared.tsx
│   ├── fresh/
│   │   ├── README.md
│   │   ├── deno.json
│   │   ├── src/
│   │   │   ├── app.ts
│   │   │   ├── app_test.tsx
│   │   │   ├── build_cache.ts
│   │   │   ├── commands.ts
│   │   │   ├── compat.ts
│   │   │   ├── compat_test.tsx
│   │   │   ├── config.ts
│   │   │   ├── config_test.ts
│   │   │   ├── constants.ts
│   │   │   ├── context.ts
│   │   │   ├── context_test.tsx
│   │   │   ├── define.ts
│   │   │   ├── define_test.ts
│   │   │   ├── dev/
│   │   │   │   ├── builder.ts
│   │   │   │   ├── builder_test.ts
│   │   │   │   ├── check.ts
│   │   │   │   ├── dev_build_cache.ts
│   │   │   │   ├── dev_build_cache_test.ts
│   │   │   │   ├── esbuild.ts
│   │   │   │   ├── file_transformer.ts
│   │   │   │   ├── file_transformer_test.ts
│   │   │   │   ├── fs_crawl.ts
│   │   │   │   ├── fs_crawl_test.ts
│   │   │   │   ├── middlewares/
│   │   │   │   │   ├── automatic_workspace_folders.ts
│   │   │   │   │   ├── error_overlay/
│   │   │   │   │   │   ├── code_frame.ts
│   │   │   │   │   │   ├── middleware.tsx
│   │   │   │   │   │   ├── middleware_test.tsx
│   │   │   │   │   │   └── overlay.tsx
│   │   │   │   │   └── live_reload.ts
│   │   │   │   ├── mod.ts
│   │   │   │   ├── update_check.ts
│   │   │   │   └── update_check_test.ts
│   │   │   ├── error.ts
│   │   │   ├── error_test.ts
│   │   │   ├── file_url.ts
│   │   │   ├── file_url_test.ts
│   │   │   ├── fs.ts
│   │   │   ├── fs_routes.ts
│   │   │   ├── fs_routes_test.tsx
│   │   │   ├── handlers.ts
│   │   │   ├── internals.ts
│   │   │   ├── internals_dev.ts
│   │   │   ├── jsonify/
│   │   │   │   ├── __snapshots__/
│   │   │   │   │   └── round_trip_test.ts.snap
│   │   │   │   ├── constants.ts
│   │   │   │   ├── custom_test.ts
│   │   │   │   ├── parse.ts
│   │   │   │   ├── round_trip_test.ts
│   │   │   │   ├── stringify.ts
│   │   │   │   └── stringify_test.ts
│   │   │   ├── middlewares/
│   │   │   │   ├── cors.ts
│   │   │   │   ├── cors_test.ts
│   │   │   │   ├── csp.ts
│   │   │   │   ├── csp_test.ts
│   │   │   │   ├── csrf.ts
│   │   │   │   ├── csrf_test.ts
│   │   │   │   ├── mod.ts
│   │   │   │   ├── mod_test.ts
│   │   │   │   ├── static_files.ts
│   │   │   │   ├── static_files_test.ts
│   │   │   │   ├── trailing_slashes.ts
│   │   │   │   └── trailing_slashes_test.ts
│   │   │   ├── mod.ts
│   │   │   ├── otel.ts
│   │   │   ├── render.ts
│   │   │   ├── router.ts
│   │   │   ├── router_test.ts
│   │   │   ├── runtime/
│   │   │   │   ├── client/
│   │   │   │   │   ├── dev.ts
│   │   │   │   │   ├── mod.ts
│   │   │   │   │   ├── partials.ts
│   │   │   │   │   ├── polyfills.ts
│   │   │   │   │   ├── preact_hooks_client.ts
│   │   │   │   │   └── reviver.ts
│   │   │   │   ├── head.ts
│   │   │   │   ├── server/
│   │   │   │   │   └── preact_hooks.ts
│   │   │   │   ├── shared.ts
│   │   │   │   └── shared_internal.ts
│   │   │   ├── segments.ts
│   │   │   ├── segments_test.ts
│   │   │   ├── server/
│   │   │   │   └── tailwind_aot_error_page.tsx
│   │   │   ├── test_utils.ts
│   │   │   ├── types.ts
│   │   │   ├── utils.ts
│   │   │   └── utils_test.ts
│   │   └── tests/
│   │       ├── active_links_test.tsx
│   │       ├── doc_examples_test.tsx
│   │       ├── fixture_head/
│   │       │   ├── islands/
│   │       │   │   ├── MetaIsland.tsx
│   │       │   │   ├── StyleIdIsland.tsx
│   │       │   │   ├── TemplateIsland.tsx
│   │       │   │   └── TitleIsland.tsx
│   │       │   └── routes/
│   │       │       ├── _app.tsx
│   │       │       ├── id.tsx
│   │       │       ├── key.tsx
│   │       │       ├── meta.tsx
│   │       │       └── title.tsx
│   │       ├── fixture_island_groups/
│   │       │   └── routes/
│   │       │       ├── both/
│   │       │       │   ├── (_islands)/
│   │       │       │   │   └── Foo.tsx
│   │       │       │   └── index.tsx
│   │       │       ├── foo/
│   │       │       │   ├── (_islands)/
│   │       │       │   │   └── Foo.tsx
│   │       │       │   └── index.tsx
│   │       │       └── index.tsx
│   │       ├── fixture_precompile/
│   │       │   ├── invalid/
│   │       │   │   ├── deno.json
│   │       │   │   ├── dev.ts
│   │       │   │   └── main.tsx
│   │       │   └── valid/
│   │       │       ├── deno.json
│   │       │       └── main.tsx
│   │       ├── fixture_update_check/
│   │       │   └── mod.ts
│   │       ├── fixtures_islands/
│   │       │   ├── Computed.tsx
│   │       │   ├── Counter.tsx
│   │       │   ├── CounterWithSlots.tsx
│   │       │   ├── EnvIsland.tsx
│   │       │   ├── EscapeIsland.tsx
│   │       │   ├── FnIsland.tsx
│   │       │   ├── FragmentIsland.tsx
│   │       │   ├── FreshAttrs.tsx
│   │       │   ├── IslandInIsland.tsx
│   │       │   ├── JsonIsland.tsx
│   │       │   ├── JsxChildrenIsland.tsx
│   │       │   ├── JsxConditional.tsx
│   │       │   ├── JsxIsland.tsx
│   │       │   ├── Multiple.tsx
│   │       │   ├── NodeProcess.tsx
│   │       │   ├── NullIsland.tsx
│   │       │   ├── OptOutPartialLink.tsx
│   │       │   ├── PartialInIsland.tsx
│   │       │   ├── PassThrough.tsx
│   │       │   ├── SelfCounter.tsx
│   │       │   └── data.json
│   │       ├── head_test.tsx
│   │       ├── islands_test.tsx
│   │       ├── lorem_ipsum.txt
│   │       ├── partials_test.tsx
│   │       ├── precompile_test.ts
│   │       └── test_utils.tsx
│   ├── init/
│   │   ├── README.md
│   │   ├── deno.json
│   │   └── src/
│   │       ├── init.ts
│   │       ├── init_test.ts
│   │       └── mod.ts
│   ├── plugin-tailwindcss/
│   │   ├── README.md
│   │   ├── deno.json
│   │   └── src/
│   │       ├── mod.ts
│   │       └── types.ts
│   ├── plugin-tailwindcss-v3/
│   │   ├── README.md
│   │   ├── deno.json
│   │   └── src/
│   │       └── mod.ts
│   ├── plugin-vite/
│   │   ├── README.md
│   │   ├── demo/
│   │   │   ├── assets/
│   │   │   │   └── style.css
│   │   │   ├── client.ts
│   │   │   ├── components/
│   │   │   │   ├── CssModuleNonIsland.tsx
│   │   │   │   └── CssModulesNonIsland.module.css
│   │   │   ├── fixtures/
│   │   │   │   ├── commonjs_mod.cjs
│   │   │   │   └── maxmind.cjs
│   │   │   ├── islands/
│   │   │   │   ├── Bar.tsx
│   │   │   │   ├── CssModules.module.css
│   │   │   │   ├── CssModules.tsx
│   │   │   │   ├── CssModulesOther.module.css
│   │   │   │   ├── CssModulesOther.tsx
│   │   │   │   ├── Foo.tsx
│   │   │   │   ├── IslandNestedInner.tsx
│   │   │   │   ├── IslandNestedOuter.tsx
│   │   │   │   └── tests/
│   │   │   │       ├── CounterHooks.tsx
│   │   │   │       ├── EnvIsland.tsx
│   │   │   │       ├── IslandAssets.tsx
│   │   │   │       ├── Mime.tsx
│   │   │   │       └── Ready.tsx
│   │   │   ├── main.ts
│   │   │   ├── routes/
│   │   │   │   ├── _error.tsx
│   │   │   │   ├── about.tsx
│   │   │   │   ├── index.tsx
│   │   │   │   └── tests/
│   │   │   │       ├── CssRoute.module.css
│   │   │   │       ├── api/
│   │   │   │       │   └── [id].tsx
│   │   │   │       ├── assets.tsx
│   │   │   │       ├── build_id.tsx
│   │   │   │       ├── commonjs.tsx
│   │   │   │       ├── css.tsx
│   │   │   │       ├── css_modules.tsx
│   │   │   │       ├── css_styles.css
│   │   │   │       ├── dep_json.tsx
│   │   │   │       ├── env.tsx
│   │   │   │       ├── env_files.tsx
│   │   │   │       ├── feed.tsx
│   │   │   │       ├── ioredis.tsx
│   │   │   │       ├── island_assets.tsx
│   │   │   │       ├── island_hooks.tsx
│   │   │   │       ├── island_nested.tsx
│   │   │   │       ├── it_works.tsx
│   │   │   │       ├── jsx_namespace.tsx
│   │   │   │       ├── maxmind.tsx
│   │   │   │       ├── middlewares/
│   │   │   │       │   ├── _middleware.ts
│   │   │   │       │   └── index.tsx
│   │   │   │       ├── mime.tsx
│   │   │   │       ├── partial.tsx
│   │   │   │       ├── partial_insert.tsx
│   │   │   │       ├── pg.tsx
│   │   │   │       ├── qs.tsx
│   │   │   │       ├── radix.tsx
│   │   │   │       ├── redis.tsx
│   │   │   │       ├── remote_island.tsx
│   │   │   │       ├── stripe.tsx
│   │   │   │       ├── supabase_pg.tsx
│   │   │   │       ├── tailwind.tsx
│   │   │   │       └── throw.tsx
│   │   │   ├── static/
│   │   │   │   ├── foo.txt
│   │   │   │   └── test_static/
│   │   │   │       ├── foo/
│   │   │   │       │   └── index.html
│   │   │   │       └── foo.txt
│   │   │   ├── utils.ts
│   │   │   └── vite.config.ts
│   │   ├── deno.json
│   │   ├── src/
│   │   │   ├── client.ts
│   │   │   ├── mod.ts
│   │   │   ├── plugins/
│   │   │   │   ├── build_id.ts
│   │   │   │   ├── client_entry.ts
│   │   │   │   ├── client_snapshot.ts
│   │   │   │   ├── deno.ts
│   │   │   │   ├── dev_server.ts
│   │   │   │   ├── patches/
│   │   │   │   │   ├── code_eval.ts
│   │   │   │   │   ├── code_eval_test.ts
│   │   │   │   │   ├── commonjs.ts
│   │   │   │   │   ├── commonjs_test.ts
│   │   │   │   │   ├── http_absolute.ts
│   │   │   │   │   ├── http_absolute_test.ts
│   │   │   │   │   ├── inline_env_vars.ts
│   │   │   │   │   ├── inline_env_vars_test.ts
│   │   │   │   │   ├── jsx_comment.ts
│   │   │   │   │   ├── jsx_comment_test.ts
│   │   │   │   │   ├── remove_polyfills.ts
│   │   │   │   │   └── remove_polyfills_test.ts
│   │   │   │   ├── patches.ts
│   │   │   │   ├── server_entry.ts
│   │   │   │   ├── server_snapshot.ts
│   │   │   │   ├── shims/
│   │   │   │   │   ├── object.entries/
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   └── supports-color/
│   │   │   │   │       └── index.ts
│   │   │   │   ├── shims.ts
│   │   │   │   └── verify_imports.ts
│   │   │   ├── shared.ts
│   │   │   └── utils.ts
│   │   └── tests/
│   │       ├── build_test.ts
│   │       ├── dev_server_test.ts
│   │       ├── fixtures/
│   │       │   ├── deno_global_island/
│   │       │   │   ├── islands/
│   │       │   │   │   └── Foo.tsx
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── deno_global_ssr/
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── island_global_name/
│   │       │   │   ├── deno.json
│   │       │   │   ├── islands/
│   │       │   │   │   └── Map.tsx
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── no_islands/
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── no_routes/
│   │       │   │   ├── main.ts
│   │       │   │   └── vite.config.ts
│   │       │   ├── no_static/
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── node_builtin/
│   │       │   │   ├── islands/
│   │       │   │   │   └── NodeIsland.tsx
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── remote_island/
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── tailwind_app/
│   │       │   │   ├── assets/
│   │       │   │   │   └── style.css
│   │       │   │   ├── client.ts
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   ├── _app.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   ├── tailwind_no_app/
│   │       │   │   ├── assets/
│   │       │   │   │   └── style.css
│   │       │   │   ├── client.ts
│   │       │   │   ├── main.ts
│   │       │   │   ├── routes/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── vite.config.ts
│   │       │   └── test_files_exclusion/
│   │       │       ├── deno.json
│   │       │       ├── main.ts
│   │       │       ├── routes/
│   │       │       │   ├── foo.test.ts
│   │       │       │   ├── index.tsx
│   │       │       │   └── index_test.tsx
│   │       │       └── vite.config.ts
│   │       └── test_utils.ts
│   └── update/
│       ├── README.md
│       ├── deno.json
│       └── src/
│           ├── mod.ts
│           ├── update.ts
│           ├── update_test.ts
│           └── utils.ts
├── tools/
│   ├── check_docs.ts
│   ├── check_links.ts
│   └── release.ts
├── versions.json
└── www/
    ├── README.md
    ├── assets/
    │   └── styles.css
    ├── client.ts
    ├── components/
    │   ├── CodeBlock.tsx
    │   ├── CodeWindow.tsx
    │   ├── CopyButton.tsx
    │   ├── DocsSidebar.tsx
    │   ├── FancyLink.tsx
    │   ├── FeatureIcons.tsx
    │   ├── Footer.tsx
    │   ├── Header.tsx
    │   ├── Icons.tsx
    │   ├── NavigationBar.tsx
    │   ├── PageSection.tsx
    │   ├── Projects.tsx
    │   ├── SideBySide.tsx
    │   ├── WaveTank.ts
    │   └── homepage/
    │       ├── CTA.tsx
    │       ├── CodeExampleBox.tsx
    │       ├── DemoBox.tsx
    │       ├── DenoSection.tsx
    │       ├── ExampleArrow.tsx
    │       ├── FormsSection.tsx
    │       ├── Hero.tsx
    │       ├── IslandsSection.tsx
    │       ├── PartialsSection.tsx
    │       ├── RecipeDemo.tsx
    │       ├── RenderingSection.tsx
    │       ├── SectionHeading.tsx
    │       ├── Simple.tsx
    │       └── SocialProof.tsx
    ├── data/
    │   ├── docs.ts
    │   └── showcase.json
    ├── deno.json
    ├── dev.ts
    ├── islands/
    │   ├── Counter.tsx
    │   ├── FormSubmitDemo.tsx
    │   ├── LemonBottom.tsx
    │   ├── LemonDrop.tsx
    │   ├── LemonTop.tsx
    │   ├── SearchButton.tsx
    │   ├── TableOfContents.tsx
    │   ├── ThemeToggle.tsx
    │   └── VersionSelect.tsx
    ├── main.ts
    ├── main_test.ts
    ├── routes/
    │   ├── _app.tsx
    │   ├── _error.tsx
    │   ├── _middleware.ts
    │   ├── docs/
    │   │   ├── [...slug].tsx
    │   │   ├── _layout.tsx
    │   │   ├── _middleware.ts
    │   │   └── index.tsx
    │   ├── index.tsx
    │   ├── raw.ts
    │   ├── recipes/
    │   │   ├── _layout.tsx
    │   │   ├── _middleware.ts
    │   │   ├── lemon-honey-tea.tsx
    │   │   ├── lemonade.tsx
    │   │   └── lemondrop.tsx
    │   ├── showcase-bak.tsx
    │   ├── showcase.tsx
    │   ├── thanks.tsx
    │   └── update.tsx
    ├── static/
    │   ├── docsearch.css
    │   ├── google40caa9e535ae39e9.html
    │   ├── markdown.css
    │   └── prism.css
    ├── utils/
    │   ├── markdown.ts
    │   ├── prism.ts
    │   ├── screenshot.ts
    │   ├── screenshot_test.ts
    │   └── state.ts
    └── vite.config.ts
Download .txt
SYMBOL INDEX (849 symbols across 251 files)

FILE: docs/toc.ts
  type RawTableOfContents (line 6) | type RawTableOfContents = Record<
  type RawTableOfContentsEntry (line 14) | interface RawTableOfContentsEntry {

FILE: packages/build-id/mod.ts
  constant DENO_DEPLOYMENT_ID (line 17) | const DENO_DEPLOYMENT_ID: string | undefined = Deno.env.get(
  constant BUILD_ID (line 30) | let BUILD_ID: string = encodeHex(buildIdHash);
  function setBuildId (line 32) | function setBuildId(buildId: string): void {

FILE: packages/examples/src/island.tsx
  function DemoIsland (line 22) | function DemoIsland(): JSX.Element {

FILE: packages/examples/src/shared.tsx
  function Doc (line 3) | function Doc(props: { children?: ComponentChildren }) {

FILE: packages/fresh/src/app.ts
  constant DEFAULT_CONN_INFO (line 35) | const DEFAULT_CONN_INFO: any = {
  type ListenOptions (line 66) | type ListenOptions =
  function createOnListen (line 73) | function createOnListen(
  function listenOnFreePort (line 124) | async function listenOnFreePort(
  class App (line 168) | class App<State> {
    method constructor (line 190) | constructor(config: FreshConfig = {}) {
    method use (line 203) | use(
    method notFound (line 226) | notFound(routeOrMiddleware: Route<State> | Middleware<State>): this {
    method onError (line 231) | onError(
    method appWrapper (line 239) | appWrapper(component: RouteComponent<State>): this {
    method layout (line 244) | layout(
    method route (line 253) | route(
    method get (line 265) | get(path: string, ...middlewares: MaybeLazy<Middleware<State>>[]): this {
    method post (line 272) | post(path: string, ...middlewares: MaybeLazy<Middleware<State>>[]): th...
    method patch (line 279) | patch(path: string, ...middlewares: MaybeLazy<Middleware<State>>[]): t...
    method put (line 286) | put(path: string, ...middlewares: MaybeLazy<Middleware<State>>[]): this {
    method delete (line 293) | delete(path: string, ...middlewares: MaybeLazy<Middleware<State>>[]): ...
    method head (line 300) | head(path: string, ...middlewares: MaybeLazy<Middleware<State>>[]): th...
    method all (line 308) | all(path: string, ...middlewares: MaybeLazy<Middleware<State>>[]): this {
    method fsRoutes (line 318) | fsRoutes(pattern = "*"): this {
    method mountApp (line 336) | mountApp(path: string, app: App<State>): this {
    method handler (line 370) | handler(): (
    method listen (line 467) | async listen(options: ListenOptions = {}): Promise<void> {

FILE: packages/fresh/src/app_test.tsx
  method component (line 648) | component() {
  method component (line 656) | component() {
  method component (line 664) | component() {
  method GET (line 797) | GET() {

FILE: packages/fresh/src/build_cache.ts
  type FileSnapshot (line 9) | interface FileSnapshot {
  type BuildSnapshot (line 16) | interface BuildSnapshot<State> {
  type StaticFile (line 25) | interface StaticFile {
  type BuildCache (line 34) | interface BuildCache<State = any> {
  class ProdBuildCache (line 46) | class ProdBuildCache<State> implements BuildCache<State> {
    method constructor (line 52) | constructor(public root: string, snapshot: BuildSnapshot<State>) {
    method getEntryAssets (line 59) | getEntryAssets(): string[] {
    method getFsRoutes (line 63) | getFsRoutes(): Command<State>[] {
    method readFile (line 67) | async readFile(pathname: string): Promise<StaticFile | null> {
  class IslandPreparer (line 92) | class IslandPreparer {
    method prepare (line 95) | prepare(

FILE: packages/fresh/src/commands.ts
  function ensureHandler (line 28) | function ensureHandler<State>(route: Route<State>) {
  type CommandType (line 40) | const enum CommandType {
  type ErrorCmd (line 51) | interface ErrorCmd<State> {
  function newErrorCmd (line 57) | function newErrorCmd<State>(
  type AppCommand (line 70) | interface AppCommand<State> {
  function newAppCmd (line 74) | function newAppCmd<State>(
  type LayoutCommand (line 80) | interface LayoutCommand<State> {
  function newLayoutCmd (line 87) | function newLayoutCmd<State>(
  type MiddlewareCmd (line 102) | interface MiddlewareCmd<State> {
  function newMiddlewareCmd (line 108) | function newMiddlewareCmd<State>(
  type NotFoundCmd (line 116) | interface NotFoundCmd<State> {
  function newNotFoundCmd (line 120) | function newNotFoundCmd<State>(
  type RouteCommand (line 131) | interface RouteCommand<State> {
  function newRouteCmd (line 138) | function newRouteCmd<State>(
  type HandlerCommand (line 165) | interface HandlerCommand<State> {
  function newHandlerCmd (line 172) | function newHandlerCmd<State>(
  type FsRouteCommand (line 187) | interface FsRouteCommand<State> {
  type Command (line 194) | type Command<State> =
  function applyCommands (line 204) | function applyCommands<State>(
  function applyCommandsInner (line 216) | function applyCommandsInner<State>(

FILE: packages/fresh/src/compat.ts
  type AppProps (line 9) | type AppProps<_Data = unknown, T = unknown> = Context<T>;
  type LayoutProps (line 13) | type LayoutProps<_Data = unknown, T = unknown> = Context<T>;
  type UnknownPageProps (line 17) | type UnknownPageProps<_Data = unknown, T = unknown> = Context<T>;
  type ErrorPageProps (line 21) | type ErrorPageProps<_Data = unknown, T = unknown> = Context<T>;
  type RouteContext (line 26) | type RouteContext<_T = never, S = Record<string, unknown>> = Context<S>;
  type Handlers (line 32) | type Handlers<T = any, State = Record<string, unknown>> = RouteHandler<
  type Handler (line 41) | type Handler<T = any, State = Record<string, unknown>> = HandlerFn<
  function defineFn (line 46) | function defineFn<State>(

FILE: packages/fresh/src/config.ts
  type FreshConfig (line 3) | interface FreshConfig {
  type ResolvedFreshConfig (line 19) | interface ResolvedFreshConfig {
  function parseDirPath (line 32) | function parseDirPath(

FILE: packages/fresh/src/constants.ts
  constant INTERNAL_PREFIX (line 1) | const INTERNAL_PREFIX = "/_frsh";
  constant DEV_ERROR_OVERLAY_URL (line 2) | const DEV_ERROR_OVERLAY_URL = `${INTERNAL_PREFIX}/error_overlay`;
  constant ALIVE_URL (line 3) | const ALIVE_URL = `${INTERNAL_PREFIX}/alive`;
  constant PARTIAL_SEARCH_PARAM (line 4) | const PARTIAL_SEARCH_PARAM = "fresh-partial";
  constant SECOND (line 6) | const SECOND = 1000;
  constant MINUTE (line 7) | const MINUTE = SECOND * 60;
  constant HOUR (line 8) | const HOUR = MINUTE * 60;
  constant DAY (line 9) | const DAY = HOUR * 24;
  constant WEEK (line 10) | const WEEK = DAY * 7;
  constant ASSET_CACHE_BUST_KEY (line 12) | const ASSET_CACHE_BUST_KEY = "__frsh_c";
  constant UPDATE_INTERVAL (line 14) | const UPDATE_INTERVAL = DAY;
  constant TEST_FILE_PATTERN (line 16) | const TEST_FILE_PATTERN = /[._]test\.(?:[tj]sx?|[mc][tj]s)$/;

FILE: packages/fresh/src/context.ts
  constant ENCODER (line 31) | const ENCODER = new TextEncoder();
  type Island (line 33) | interface Island {
  type ServerIslandRegistry (line 41) | type ServerIslandRegistry = Map<ComponentType, Island>;
  type UiTree (line 45) | interface UiTree<Data, State> {
  type FreshContext (line 53) | type FreshContext<State = unknown> = Context<State>;
  class Context (line 62) | class Context<State> {
    method constructor (line 134) | constructor(
    method redirect (line 168) | redirect(pathOrUrl: string, status = 302): Response {
    method render (line 199) | async render(
    method text (line 384) | text(content: string, init?: ResponseInit): Response {
    method html (line 394) | html(content: string, init?: ResponseInit): Response {
    method json (line 409) | json(content: any, init?: ResponseInit): Response {
    method stream (line 437) | stream<U extends string | Uint8Array>(
  function getHeadersFromInit (line 467) | function getHeadersFromInit(init?: ResponseInit) {

FILE: packages/fresh/src/define.ts
  type Define (line 12) | interface Define<State> {
  function createDefine (line 170) | function createDefine<State>(): Define<State> {

FILE: packages/fresh/src/define_test.ts
  method GET (line 14) | GET(ctx) {

FILE: packages/fresh/src/dev/builder.ts
  type BuildOptions (line 30) | interface BuildOptions {
  type ResolvedBuildConfig (line 101) | type ResolvedBuildConfig = Required<Omit<BuildOptions, "sourceMap">> & {
  class Builder (line 108) | class Builder<State = any> {
    method constructor (line 116) | constructor(options?: BuildOptions) {
    method registerIsland (line 143) | registerIsland(specifier: string): void {
    method onTransformStaticFile (line 147) | onTransformStaticFile(
    method listen (line 154) | async listen(
    method build (line 233) | async build(
    method #crawlFsItems (line 263) | async #crawlFsItems() {
    method #build (line 279) | async #build<T>(buildCache: DevBuildCache<T>, dev: boolean): Promise<v...
  function specToName (line 362) | function specToName(spec: string): string {

FILE: packages/fresh/src/dev/builder_test.ts
  method onListen (line 414) | async onListen(addr) {
  method onListen (line 448) | onListen(addr) {
  method onListen (line 488) | async onListen(addr) {
  method onListen (line 589) | async onListen(addr) {

FILE: packages/fresh/src/dev/check.ts
  type DenoConfig (line 4) | interface DenoConfig {
  function checkDenoCompilerOptions (line 13) | async function checkDenoCompilerOptions(root: string) {
  function findNearestDenoConfigWithCompilerOptions (line 56) | async function findNearestDenoConfigWithCompilerOptions(

FILE: packages/fresh/src/dev/dev_build_cache.ts
  constant WINDOWS_SEPARATOR (line 18) | const WINDOWS_SEPARATOR = pathWin32.SEPARATOR;
  type MemoryFile (line 20) | interface MemoryFile {
  type IslandModChunk (line 26) | interface IslandModChunk {
  type FsRouteFileNoMod (line 33) | type FsRouteFileNoMod<State> = Omit<FsRouteFile<State>, "mod"> & {
  type FsRoute (line 37) | interface FsRoute<State> {
  type DevBuildCache (line 43) | interface DevBuildCache<State> extends BuildCache<State> {
  class MemoryBuildCache (line 55) | class MemoryBuildCache<State> implements DevBuildCache<State> {
    method constructor (line 68) | constructor(
    method getEntryAssets (line 85) | getEntryAssets(): string[] {
    method getFsRoutes (line 89) | getFsRoutes(): Command<State>[] {
    method readFile (line 93) | async readFile(pathname: string): Promise<StaticFile | null> {
    method addUnprocessedFile (line 176) | addUnprocessedFile(pathname: string, dir: string): void {
    method addProcessedFile (line 184) | async addProcessedFile(
    method flush (line 196) | async flush(): Promise<void> {
    method prepare (line 216) | async prepare(): Promise<void> {
  class DiskBuildCache (line 229) | class DiskBuildCache<State> implements DevBuildCache<State> {
    method constructor (line 241) | constructor(
    method getEntryAssets (line 255) | getEntryAssets(): string[] {
    method getFsRoutes (line 259) | getFsRoutes(): Command<State>[] {
    method addUnprocessedFile (line 263) | addUnprocessedFile(pathname: string, dir: string): void {
    method addProcessedFile (line 270) | async addProcessedFile(
    method readFile (line 288) | async readFile(_pathname: string): Promise<StaticFile | null> {
    method prepare (line 292) | async prepare(): Promise<void> {
    method flush (line 296) | async flush(): Promise<void> {
  constant EDIT_WARNING (line 389) | const EDIT_WARNING =
  function hashContent (line 392) | async function hashContent(
  function getContentType (line 406) | function getContentType(filePath: string): string {
  function maybeToFileUrl (line 411) | function maybeToFileUrl(file: string) {
  type PendingStaticFile (line 415) | interface PendingStaticFile {
  function writeCompiledEntry (line 421) | async function writeCompiledEntry(outDir: string) {
  function generateSnapshotServer (line 433) | async function generateSnapshotServer(
  function prepareStaticFile (line 532) | async function prepareStaticFile(
  function generateServerEntry (line 552) | function generateServerEntry(
  function getClientEntry (line 585) | function getClientEntry(buildId: string) {

FILE: packages/fresh/src/dev/esbuild.ts
  type FreshBundleOptions (line 5) | interface FreshBundleOptions {
  type BuildOutput (line 24) | interface BuildOutput {
  constant PREACT_ENV (line 32) | const PREACT_ENV = Deno.env.get("PREACT_PATH");
  function bundleJs (line 34) | async function bundleJs(
  function startEsbuild (line 158) | async function startEsbuild() {
  function buildIdPlugin (line 169) | function buildIdPlugin(buildId: string): EsbuildPlugin {
  function toPreactModPath (line 191) | function toPreactModPath(mod: string): string {
  function preactDebugger (line 207) | function preactDebugger(preactPath: string | undefined): EsbuildPlugin {
  function windowsPathFixer (line 224) | function windowsPathFixer(): EsbuildPlugin {

FILE: packages/fresh/src/dev/file_transformer.ts
  type TransformMode (line 6) | type TransformMode = "development" | "production";
  type OnTransformOptions (line 8) | interface OnTransformOptions {
  type OnTransformResult (line 14) | interface OnTransformResult {
  type OnTransformArgs (line 20) | interface OnTransformArgs {
  type TransformFn (line 28) | type TransformFn = (
  type Transformer (line 40) | interface Transformer {
  type ProcessedFile (line 45) | interface ProcessedFile {
  type TransformReq (line 52) | interface TransformReq {
  class FileTransformer (line 60) | class FileTransformer {
    method constructor (line 65) | constructor(fs: FsAdapter, root: string) {
    method onTransform (line 70) | onTransform(options: OnTransformOptions, callback: TransformFn): void {
    method process (line 74) | async process(
  constant CSS_URL_REGEX (line 248) | const CSS_URL_REGEX = /url\(("[^"]+"|'[^']+'|[^)]+)\)/g;
  function cssAssetHash (line 250) | function cssAssetHash(transformer: FileTransformer) {

FILE: packages/fresh/src/dev/file_transformer_test.ts
  function testTransformer (line 6) | function testTransformer(files: Record<string, string>, root = "/") {
  function consumeResult (line 30) | function consumeResult(result: ProcessedFile[]) {

FILE: packages/fresh/src/dev/fs_crawl.ts
  constant GROUP_REG (line 10) | const GROUP_REG = /[/\\\\]\((_[^/\\\\]+)\)[/\\\\]/;
  function crawlRouteDir (line 12) | async function crawlRouteDir<State>(
  function walkDir (line 104) | async function walkDir(
  function crawlFsItem (line 124) | async function crawlFsItem(

FILE: packages/fresh/src/dev/middlewares/automatic_workspace_folders.ts
  function automaticWorkspaceFolders (line 22) | function automaticWorkspaceFolders<T>(root: string): Middleware<T> {

FILE: packages/fresh/src/dev/middlewares/error_overlay/code_frame.ts
  function tabs2Spaces (line 3) | function tabs2Spaces(str: string) {
  function createCodeFrame (line 11) | function createCodeFrame(
  constant STACK_FRAME (line 78) | const STACK_FRAME = /^\s*at\s+(?:(.*)\s+)?\((.*):(\d+):(\d+)\)$/;
  type StackFrame (line 79) | interface StackFrame {
  function getFirstUserFile (line 85) | function getFirstUserFile(
  function getCodeFrame (line 115) | function getCodeFrame(stack: string, rootDir: string) {

FILE: packages/fresh/src/dev/middlewares/error_overlay/middleware.tsx
  function devErrorOverlay (line 7) | function devErrorOverlay<T>(): Middleware<T> {

FILE: packages/fresh/src/dev/middlewares/error_overlay/overlay.tsx
  function CodeFrame (line 95) | function CodeFrame(props: { codeFrame: string }) {
  constant DEFAULT_MESSAGE (line 119) | const DEFAULT_MESSAGE = "Internal Server Error";
  function ErrorOverlay (line 121) | function ErrorOverlay(props: { url: URL }) {

FILE: packages/fresh/src/dev/middlewares/live_reload.ts
  function liveReload (line 5) | function liveReload<T>(): Middleware<T> {

FILE: packages/fresh/src/dev/update_check.ts
  type CheckFile (line 6) | interface CheckFile {
  function getHomeDir (line 13) | function getHomeDir(): string | null {
  function getFreshCacheDir (line 37) | function getFreshCacheDir(): string | null {
  function fetchLatestVersion (line 43) | async function fetchLatestVersion(): Promise<string> {
  function readCurrentVersion (line 52) | function readCurrentVersion(): string {
  function updateCheck (line 56) | async function updateCheck(

FILE: packages/fresh/src/dev/update_check_test.ts
  constant CURRENT_VERSION (line 10) | const CURRENT_VERSION = denoJson.version;

FILE: packages/fresh/src/error.ts
  class HttpError (line 33) | class HttpError extends Error {
    method constructor (line 69) | constructor(

FILE: packages/fresh/src/file_url.ts
  type FileUrl (line 4) | type FileUrl = string & { readonly __brand: unique symbol };
  function pathToFileUrl (line 6) | function pathToFileUrl(str: string): FileUrl {
  function relativeUrl (line 18) | function relativeUrl(from: FileUrl, to: FileUrl): string {

FILE: packages/fresh/src/fs.ts
  type FsAdapter (line 3) | interface FsAdapter {
  method isDirectory (line 18) | async isDirectory(path) {
  method mkdirp (line 27) | async mkdirp(dir: string) {

FILE: packages/fresh/src/fs_routes.ts
  type FreshFsMod (line 20) | interface FreshFsMod<State> {
  type FsRouteFile (line 30) | interface FsRouteFile<State> {
  function isFreshFile (line 41) | function isFreshFile<State>(
  type FsRoutesOptions (line 55) | interface FsRoutesOptions {
  function fsItemsToCommands (line 67) | function fsItemsToCommands<State>(
  function warnInvalidRoute (line 191) | function warnInvalidRoute(message: string) {
  constant APP_REG (line 199) | const APP_REG = /_app(?!\.[tj]sx?)?$/;
  function sortRoutePaths (line 205) | function sortRoutePaths(a: string, b: string) {
  function getRoutePathScore (line 280) | function getRoutePathScore(char: string, s: string, i: number): number {
  function validateFsMod (line 304) | function validateFsMod<State>(
  function normalizeRoute (line 328) | function normalizeRoute<State>(

FILE: packages/fresh/src/fs_routes_test.tsx
  function createServer (line 15) | async function createServer<T>(
  method handler (line 180) | handler(ctx) {
  method GET (line 681) | GET() {
  method GET (line 688) | GET() {
  method GET (line 722) | GET() {
  method GET (line 807) | GET() {

FILE: packages/fresh/src/handlers.ts
  type PageResponse (line 4) | interface PageResponse<T> {
  function page (line 39) | function page<T>(data?: T, options?: {
  type RouteHandler (line 96) | type RouteHandler<Data, State> =
  function isHandlerByMethod (line 100) | function isHandlerByMethod<D, S>(
  type HandlerFn (line 193) | interface HandlerFn<Data, State> {
  type HandlerByMethod (line 205) | type HandlerByMethod<Data, State> = {
  type RouteData (line 209) | type RouteData<

FILE: packages/fresh/src/jsonify/constants.ts
  constant UNDEFINED (line 1) | const UNDEFINED = -1;
  constant NULL (line 2) | const NULL = -2;
  constant NAN (line 3) | const NAN = -3;
  constant INFINITY_POS (line 4) | const INFINITY_POS = -4;
  constant INFINITY_NEG (line 5) | const INFINITY_NEG = -5;
  constant ZERO_NEG (line 6) | const ZERO_NEG = -6;
  constant HOLE (line 7) | const HOLE = -7;

FILE: packages/fresh/src/jsonify/custom_test.ts
  class Point (line 7) | class Point {
    method constructor (line 8) | constructor(public x: number, public y: number) {

FILE: packages/fresh/src/jsonify/parse.ts
  type CustomParser (line 12) | type CustomParser = Record<string, (value: any) => unknown>;
  function parse (line 14) | function parse<T = unknown>(
  function unpack (line 25) | function unpack(
  function b64decode (line 124) | function b64decode(b64: string): Uint8Array {

FILE: packages/fresh/src/jsonify/round_trip_test.ts
  constant TESTS (line 13) | const TESTS = [

FILE: packages/fresh/src/jsonify/stringify.ts
  type Stringifiers (line 11) | type Stringifiers = Record<
  function stringify (line 38) | function stringify(data: unknown, custom?: Stringifiers): string {
  function serializeInner (line 48) | function serializeInner(
  function b64encode (line 167) | function b64encode(buffer: ArrayBufferLike): string {

FILE: packages/fresh/src/middlewares/cors.ts
  type CORSOptions (line 4) | type CORSOptions<State> = {
  function cors (line 66) | function cors<State>(options?: CORSOptions<State>): Middleware<State> {

FILE: packages/fresh/src/middlewares/csp.ts
  type CSPOptions (line 4) | interface CSPOptions {
  function csp (line 31) | function csp<State>(options: CSPOptions = {}): Middleware<State> {

FILE: packages/fresh/src/middlewares/csrf.ts
  type CsrfOptions (line 7) | interface CsrfOptions<State = any> {
  function csrf (line 55) | function csrf<State>(

FILE: packages/fresh/src/middlewares/csrf_test.ts
  function testHandler (line 6) | function testHandler<T>(
  function createTests (line 15) | function createTests(trusted: CsrfOptions["origin"]) {

FILE: packages/fresh/src/middlewares/mod.ts
  type Middleware (line 75) | type Middleware<State> = (
  type MiddlewareFn (line 82) | type MiddlewareFn<State> = Middleware<State>;
  type MaybeLazyMiddleware (line 87) | type MaybeLazyMiddleware<State> = (
  function runMiddlewares (line 91) | async function runMiddlewares<State>(

FILE: packages/fresh/src/middlewares/mod_test.ts
  type State (line 57) | type State = { text: string };
  type State (line 143) | type State = { text: string };

FILE: packages/fresh/src/middlewares/static_files.ts
  function staticFiles (line 14) | function staticFiles<T>(): Middleware<T> {

FILE: packages/fresh/src/middlewares/static_files_test.ts
  class MockBuildCache (line 11) | class MockBuildCache implements BuildCache {
    method constructor (line 19) | constructor(files: Record<string, { hash: string | null; content: stri...
    method getEntryAssets (line 35) | getEntryAssets(): string[] {
    method getFsRoutes (line 40) | getFsRoutes(): Command<any>[] {
    method readFile (line 45) | async readFile(pathname: string): Promise<StaticFile | null> {

FILE: packages/fresh/src/middlewares/trailing_slashes.ts
  function trailingSlashes (line 13) | function trailingSlashes<State>(

FILE: packages/fresh/src/otel.ts
  constant CURRENT_FRESH_VERSION (line 4) | const CURRENT_FRESH_VERSION = denoJson.version;
  function recordSpanError (line 9) | function recordSpanError(span: Span, err: unknown) {

FILE: packages/fresh/src/render.ts
  type AsyncAnyComponent (line 11) | type AsyncAnyComponent<P> = {
  function isAsyncAnyComponent (line 23) | function isAsyncAnyComponent(fn: any): fn is AsyncAnyComponent<any> {
  function renderAsyncAnyComponent (line 27) | async function renderAsyncAnyComponent<Props>(
  type PageProps (line 52) | type PageProps<Data = unknown, T = unknown> =
  type ComponentDef (line 68) | interface ComponentDef<Data, State> {
  function renderRouteComponent (line 73) | async function renderRouteComponent<State>(

FILE: packages/fresh/src/router.ts
  type Method (line 1) | type Method =
  type RouteByMethod (line 10) | type RouteByMethod<T> = {
  type StaticRouteDef (line 14) | interface StaticRouteDef<T> {
  type DynamicRouteDef (line 19) | interface DynamicRouteDef<T> {
  function newByMethod (line 24) | function newByMethod<T>(): RouteByMethod<T> {
  type RouteResult (line 36) | interface RouteResult<T> {
  type Router (line 43) | interface Router<T> {
  constant IS_PATTERN (line 53) | const IS_PATTERN = /[*:{}+?()]/;
  constant EMPTY (line 55) | const EMPTY: string[] = [];
  class UrlPatternRouter (line 57) | class UrlPatternRouter<T> implements Router<T> {
    method getAllowedMethods (line 63) | getAllowedMethods(pattern: string): string[] {
    method add (line 69) | add(
    method match (line 111) | match(method: Method, url: URL, init: T[] = []): RouteResult<T> {
  function pathToPattern (line 168) | function pathToPattern(
  function patternToSegments (line 265) | function patternToSegments(
  function mergePath (line 294) | function mergePath(
  function toRoutePath (line 309) | function toRoutePath(path: string): string {

FILE: packages/fresh/src/runtime/client/dev.ts
  function reconnect (line 31) | function reconnect() {
  function onOpenWs (line 54) | function onOpenWs() {
  function onCloseWs (line 58) | function onCloseWs() {
  function connect (line 63) | function connect() {
  function disconnect (line 75) | function disconnect() {
  function handleMessage (line 83) | function handleMessage(e: MessageEvent) {
  function handleError (line 107) | function handleError(e: Event) {

FILE: packages/fresh/src/runtime/client/partials.ts
  constant PARTIAL_ATTR (line 26) | const PARTIAL_ATTR = "f-partial";
  class NoPartialsError (line 28) | class NoPartialsError extends Error {}
  type FreshHistoryState (line 33) | interface FreshHistoryState {
  function checkClientNavEnabled (line 40) | function checkClientNavEnabled(el: HTMLElement) {
  function maybeUpdateHistory (line 58) | function maybeUpdateHistory(nextUrl: URL) {
  function updateLinks (line 262) | function updateLinks(url: URL) {
  function fetchPartials (line 282) | async function fetchPartials(
  type PartialReviveCtx (line 307) | interface PartialReviveCtx {
  function applyPartials (line 314) | async function applyPartials(res: Response): Promise<void> {
  function revivePartials (line 425) | function revivePartials(

FILE: packages/fresh/src/runtime/client/preact_hooks_client.ts
  function applyProps (line 103) | function applyProps(props: Record<string, any>, el: HTMLElement) {

FILE: packages/fresh/src/runtime/client/reviver.ts
  type RootKind (line 14) | const enum RootKind {
  type IslandReq (line 19) | interface IslandReq {
  type PartialReq (line 27) | interface PartialReq {
  type ReviveContext (line 35) | interface ReviveContext {
  type SlotRef (line 42) | interface SlotRef {
  constant SLOT_SYMBOL (line 47) | const SLOT_SYMBOL = Symbol.for("_FRESH_SLOT");
  function isSlotRef (line 48) | function isSlotRef(x: unknown): x is SlotRef {
  type DeserializedProps (line 53) | type DeserializedProps = {
  constant ACTIVE_PARTIALS (line 58) | const ACTIVE_PARTIALS = new Map<string, PartialComp>();
  class PartialComp (line 60) | class PartialComp extends Component<
    method componentDidMount (line 63) | override componentDidMount() {
    method render (line 67) | render() {
  function revive (line 73) | function revive(
  constant ISLAND_REGISTRY (line 127) | const ISLAND_REGISTRY = new Map<string, ComponentType>();
  constant CUSTOM_PARSER (line 129) | const CUSTOM_PARSER: CustomParser = {
  function createReviveCtx (line 137) | function createReviveCtx(): ReviveContext {
  function boot (line 146) | function boot(
  constant SHOW_MARKERS (line 195) | const SHOW_MARKERS = false;
  type FreshMarker (line 197) | interface FreshMarker extends Text {
  function isFreshMarkerText (line 201) | function isFreshMarkerText(node: Node): node is FreshMarker {
  function maybeHideMarker (line 211) | function maybeHideMarker(marker: Comment): Comment | Text {
  function _walkInner (line 220) | function _walkInner(
  type Marker (line 301) | const enum Marker {
  type ServerSlotProps (line 307) | interface ServerSlotProps {
  function ServerSlot (line 314) | function ServerSlot(props: ServerSlotProps): any {
  function domToVNode (line 318) | function domToVNode(
  function addVNodeChild (line 491) | function addVNodeChild(parent: VNode<any>, child: VNode<any> | string) {
  function copyOldChildren (line 499) | function copyOldChildren(
  function isCommentNode (line 508) | function isCommentNode(node: Node): node is Comment {
  function isTextNode (line 511) | function isTextNode(node: Node): node is Text {
  function isElementNode (line 514) | function isElementNode(node: Node): node is HTMLElement {
  function createRootFragment (line 518) | function createRootFragment(

FILE: packages/fresh/src/runtime/head.ts
  type HeadProps (line 5) | interface HeadProps {
  function Head (line 9) | function Head(props: HeadProps): ComponentChildren {

FILE: packages/fresh/src/runtime/server/preact_hooks.ts
  type InternalPreactOptions (line 39) | interface InternalPreactOptions extends PreactOptions {
  type InternalVNode (line 53) | interface InternalVNode extends VNode {
  class RenderState (line 61) | class RenderState {
    method constructor (line 85) | constructor(
    method clear (line 94) | clear() {
  constant RENDER_STATE (line 104) | let RENDER_STATE: RenderState | null = null;
  function setRenderState (line 105) | function setRenderState(state: RenderState | null) {
  constant PATCHED (line 164) | const PATCHED = new WeakSet<VNode>();
  function normalizeKey (line 166) | function normalizeKey(key: unknown): string {
  function RemainingHead (line 418) | function RemainingHead() {
  type SlotProps (line 446) | interface SlotProps {
  function Slot (line 451) | function Slot(props: SlotProps) {
  function hasIslandOwner (line 461) | function hasIslandOwner(current: RenderState, vnode: VNode): boolean {
  function wrapWithMarker (line 474) | function wrapWithMarker(
  function isSignal (line 495) | function isSignal(x: any): x is Signal {
  function isComputedSignal (line 505) | function isComputedSignal(x: any): x is ReadonlySignal {
  function isVNode (line 512) | function isVNode(x: any): x is VNode {
  function FreshScripts (line 538) | function FreshScripts() {
  type PartialStateJson (line 566) | interface PartialStateJson {
  function FreshRuntimeScript (line 575) | function FreshRuntimeScript() {
  function ShowErrorOverlay (line 650) | function ShowErrorOverlay() {

FILE: packages/fresh/src/runtime/shared.ts
  constant IS_BROWSER (line 21) | const IS_BROWSER = typeof document !== "undefined";
  function asset (line 28) | function asset(path: string): string {
  function assetSrcSet (line 33) | function assetSrcSet(srcset: string): string {
  type PartialProps (line 37) | interface PartialProps {
  function Partial (line 50) | function Partial(props: PartialProps): VNode {

FILE: packages/fresh/src/runtime/shared_internal.ts
  constant DATA_CURRENT (line 4) | const DATA_CURRENT = "data-current";
  constant DATA_ANCESTOR (line 5) | const DATA_ANCESTOR = "data-ancestor";
  constant DATA_FRESH_KEY (line 6) | const DATA_FRESH_KEY = "data-frsh-key";
  constant CLIENT_NAV_ATTR (line 7) | const CLIENT_NAV_ATTR = "f-client-nav";
  type OptionsType (line 9) | const enum OptionsType {
  type InternalVNode (line 19) | interface InternalVNode extends VNode {
  type InternalPreactOptions (line 24) | interface InternalPreactOptions extends PreactOptions {
  type UrlMatchKind (line 38) | const enum UrlMatchKind {
  function matchesUrl (line 44) | function matchesUrl(current: string, needle: string): UrlMatchKind {
  function setActiveUrl (line 67) | function setActiveUrl(vnode: VNode, pathname: string): void {
  type PartialMode (line 82) | const enum PartialMode {
  function assetInternal (line 93) | function assetInternal(path: string, buildId: string): string {
  function assetSrcSetInternal (line 116) | function assetSrcSetInternal(srcset: string, buildId: string): string {
  function assetHashingHook (line 134) | function assetHashingHook(

FILE: packages/fresh/src/segments.ts
  type RouteComponent (line 15) | type RouteComponent<State> =
  type Segment (line 19) | interface Segment<State> {
  function newSegment (line 33) | function newSegment<State>(
  function getOrCreateSegment (line 49) | function getOrCreateSegment<State>(
  function segmentToMiddlewares (line 75) | function segmentToMiddlewares<State>(
  function renderRoute (line 143) | async function renderRoute<State>(

FILE: packages/fresh/src/server/tailwind_aot_error_page.tsx
  constant LINK (line 1) | const LINK = "https://fresh.deno.dev/docs/concepts/ahead-of-time-builds";
  function TailwindErrorPage (line 3) | function TailwindErrorPage() {

FILE: packages/fresh/src/test_utils.ts
  constant STUB (line 11) | const STUB = {} as unknown as Deno.ServeHandlerInfo;
  class FakeServer (line 13) | class FakeServer {
    method constructor (line 14) | constructor(
    method get (line 21) | async get(path: string, init?: RequestInit): Promise<Response> {
    method post (line 26) | async post(path: string, body?: BodyInit): Promise<Response> {
    method patch (line 31) | async patch(path: string, body?: BodyInit): Promise<Response> {
    method put (line 36) | async put(path: string, body?: BodyInit): Promise<Response> {
    method delete (line 41) | async delete(path: string): Promise<Response> {
    method head (line 46) | async head(path: string): Promise<Response> {
    method options (line 51) | async options(path: string): Promise<Response> {
    method request (line 57) | async request(req: Request): Promise<Response> {
    method toUrl (line 61) | private toUrl(path: string) {
  constant DEFAULT_CONFIG (line 66) | const DEFAULT_CONFIG: ResolvedFreshConfig = {
  function serveMiddleware (line 72) | function serveMiddleware<T>(
  function createFakeFs (line 102) | function createFakeFs(files: Record<string, unknown>): FsAdapter {
  function withTmpDir (line 139) | async function withTmpDir(
  class MockBuildCache (line 160) | class MockBuildCache<State> implements BuildCache<State> {
    method constructor (line 167) | constructor(files: FsRouteFile<State>[], mode: "development" | "produc...
    method getEntryAssets (line 172) | getEntryAssets(): string[] {
    method getFsRoutes (line 176) | getFsRoutes(): Command<State>[] {
    method readFile (line 180) | readFile(_pathname: string): Promise<StaticFile | null> {
  function writeFiles (line 185) | async function writeFiles(dir: string, files: Record<string, string>) {

FILE: packages/fresh/src/types.ts
  type RouteConfig (line 5) | interface RouteConfig {
  type LayoutConfig (line 41) | interface LayoutConfig {
  type Route (line 55) | interface Route<State> {
  type Lazy (line 67) | type Lazy<T> = () => Promise<T>;
  type MaybeLazy (line 72) | type MaybeLazy<T> = T | Lazy<T>;

FILE: packages/fresh/src/utils.ts
  function assertInDir (line 5) | function assertInDir(
  function pathToExportName (line 33) | function pathToExportName(filePath: string): string {
  constant SCRIPT_ESCAPE (line 40) | const SCRIPT_ESCAPE = /<\/(style|script)/gi;
  constant COMMENT_ESCAPE (line 41) | const COMMENT_ESCAPE = /<!--/gi;
  function escapeScript (line 44) | function escapeScript(
  class UniqueNamer (line 53) | class UniqueNamer {
    method getUniqueName (line 56) | getUniqueName(name: string): string {
  constant JS_RESERVED (line 80) | const JS_RESERVED = new Set([
  constant PATH_TO_SPEC (line 246) | const PATH_TO_SPEC = /[\\/]+/g;
  function pathToSpec (line 247) | function pathToSpec(outDir: string, spec: string): string {
  function maybeDot (line 279) | function maybeDot(spec: string): string {
  function isLazy (line 283) | function isLazy<T>(value: MaybeLazy<T>): value is Lazy<T> {

FILE: packages/fresh/tests/active_links_test.tsx
  function testApp (line 17) | function testApp<T>(): App<T> {
  function View (line 28) | function View() {
  function PartialPage (line 89) | function PartialPage() {

FILE: packages/fresh/tests/doc_examples_test.tsx
  function extractTsCode (line 101) | async function extractTsCode(path: string) {

FILE: packages/fresh/tests/fixture_head/islands/MetaIsland.tsx
  function MetaIsland (line 4) | function MetaIsland() {

FILE: packages/fresh/tests/fixture_head/islands/StyleIdIsland.tsx
  function StyleIdIsland (line 4) | function StyleIdIsland() {

FILE: packages/fresh/tests/fixture_head/islands/TemplateIsland.tsx
  function TemplateIsland (line 4) | function TemplateIsland() {

FILE: packages/fresh/tests/fixture_head/islands/TitleIsland.tsx
  function TitleIsland (line 4) | function TitleIsland() {

FILE: packages/fresh/tests/fixture_head/routes/_app.tsx
  function Page (line 3) | function Page({ Component }: PageProps) {

FILE: packages/fresh/tests/fixture_head/routes/id.tsx
  function Page (line 3) | function Page() {

FILE: packages/fresh/tests/fixture_head/routes/key.tsx
  function Page (line 3) | function Page() {

FILE: packages/fresh/tests/fixture_head/routes/meta.tsx
  function Page (line 3) | function Page() {

FILE: packages/fresh/tests/fixture_head/routes/title.tsx
  function Page (line 3) | function Page() {

FILE: packages/fresh/tests/fixture_island_groups/routes/both/(_islands)/Foo.tsx
  function Foo (line 4) | function Foo() {

FILE: packages/fresh/tests/fixture_island_groups/routes/both/index.tsx
  function Home (line 4) | function Home() {

FILE: packages/fresh/tests/fixture_island_groups/routes/foo/(_islands)/Foo.tsx
  function Foo (line 4) | function Foo() {

FILE: packages/fresh/tests/fixture_island_groups/routes/foo/index.tsx
  function Home (line 3) | function Home() {

FILE: packages/fresh/tests/fixture_island_groups/routes/index.tsx
  function Home (line 1) | function Home() {

FILE: packages/fresh/tests/fixture_update_check/mod.ts
  function getLatestVersion (line 5) | async function getLatestVersion() {
  function getCurrentVersion (line 11) | function getCurrentVersion() {

FILE: packages/fresh/tests/fixtures_islands/Computed.tsx
  function ComputedSignal (line 4) | function ComputedSignal(props: { id?: string }) {

FILE: packages/fresh/tests/fixtures_islands/Counter.tsx
  type CounterProps (line 4) | interface CounterProps {
  function Counter (line 9) | function Counter(props: CounterProps) {

FILE: packages/fresh/tests/fixtures_islands/CounterWithSlots.tsx
  function CounterWithSlots (line 5) | function CounterWithSlots(

FILE: packages/fresh/tests/fixtures_islands/EnvIsland.tsx
  type EnvIslandProps (line 5) | interface EnvIslandProps {
  function EnvIsland (line 9) | function EnvIsland(props: EnvIslandProps) {

FILE: packages/fresh/tests/fixtures_islands/EscapeIsland.tsx
  function EscapeIsland (line 4) | function EscapeIsland(props: { str: string }) {

FILE: packages/fresh/tests/fixtures_islands/FnIsland.tsx
  function Foo (line 7) | function Foo(props: { children: () => VNode }) {
  function FnIsland (line 11) | function FnIsland() {

FILE: packages/fresh/tests/fixtures_islands/FragmentIsland.tsx
  function FragmentIsland (line 2) | function FragmentIsland() {

FILE: packages/fresh/tests/fixtures_islands/FreshAttrs.tsx
  type FreshAttrs (line 4) | interface FreshAttrs {
  function FreshAttrs (line 8) | function FreshAttrs(props: FreshAttrs) {

FILE: packages/fresh/tests/fixtures_islands/IslandInIsland.tsx
  function IslandInIsland (line 4) | function IslandInIsland() {

FILE: packages/fresh/tests/fixtures_islands/JsonIsland.tsx
  function JsonIsland (line 3) | function JsonIsland() {

FILE: packages/fresh/tests/fixtures_islands/JsxChildrenIsland.tsx
  type JsxIslandProps (line 5) | interface JsxIslandProps {
  function JsxChildrenIsland (line 9) | function JsxChildrenIsland(props: JsxIslandProps) {

FILE: packages/fresh/tests/fixtures_islands/JsxConditional.tsx
  type JsxConditionalProps (line 5) | interface JsxConditionalProps {
  function JsxConditional (line 10) | function JsxConditional(props: JsxConditionalProps) {

FILE: packages/fresh/tests/fixtures_islands/JsxIsland.tsx
  type JsxIslandProps (line 5) | interface JsxIslandProps {
  function JsxIsland (line 10) | function JsxIsland(props: JsxIslandProps) {

FILE: packages/fresh/tests/fixtures_islands/Multiple.tsx
  type MultipleProps (line 5) | interface MultipleProps {
  function Multiple1 (line 10) | function Multiple1(props: MultipleProps) {
  function Multiple2 (line 14) | function Multiple2(props: MultipleProps) {

FILE: packages/fresh/tests/fixtures_islands/NodeProcess.tsx
  function NodeProcess (line 5) | function NodeProcess() {

FILE: packages/fresh/tests/fixtures_islands/NullIsland.tsx
  function NullIsland (line 3) | function NullIsland() {

FILE: packages/fresh/tests/fixtures_islands/OptOutPartialLink.tsx
  function OptOutPartialLink (line 1) | function OptOutPartialLink(props: { href: string; partial: string }) {

FILE: packages/fresh/tests/fixtures_islands/PartialInIsland.tsx
  function PartialInIsland (line 3) | function PartialInIsland() {

FILE: packages/fresh/tests/fixtures_islands/PassThrough.tsx
  function PassThrough (line 3) | function PassThrough(props: { children?: ComponentChildren }) {

FILE: packages/fresh/tests/fixtures_islands/SelfCounter.tsx
  type SelfCounterProps (line 4) | interface SelfCounterProps {
  function SelfCounter (line 8) | function SelfCounter(props: SelfCounterProps) {

FILE: packages/fresh/tests/islands_test.tsx
  function testApp (line 38) | function testApp(config?: FreshConfig): App<unknown> {
  function testGroupApp (line 48) | function testGroupApp(config?: FreshConfig): App<unknown> {

FILE: packages/fresh/tests/partials_test.tsx
  function testApp (line 31) | function testApp<T>(): App<T> {
  function Foo (line 758) | function Foo(props: { id: string }) {

FILE: packages/fresh/tests/test_utils.tsx
  function Doc (line 32) | function Doc(props: { children?: ComponentChildren; title?: string }) {
  constant ALL_ISLAND_DIR (line 47) | const ALL_ISLAND_DIR = path.join(
  constant ISLAND_GROUP_DIR (line 51) | const ISLAND_GROUP_DIR = path.join(
  function buildProd (line 56) | async function buildProd(
  function withBrowserApp (line 64) | async function withBrowserApp(
  function withBrowser (line 84) | async function withBrowser(fn: (page: Page) => void | Promise<void>) {
  type TestChildServerOptions (line 98) | interface TestChildServerOptions {
  function withChildProcessServer (line 105) | async function withChildProcessServer(
  constant VOID_ELEMENTS (line 175) | const VOID_ELEMENTS =
  function prettyDom (line 177) | function prettyDom(doc: Document) {
  function _printDomNode (line 186) | function _printDomNode(
  type TestDocument (line 237) | interface TestDocument extends Document {
  function parseHtml (line 241) | function parseHtml(input: string): TestDocument {
  function assertSelector (line 252) | function assertSelector(doc: Document, selector: string) {
  function assertNotSelector (line 261) | function assertNotSelector(doc: Document, selector: string) {
  function assertMetaContent (line 270) | function assertMetaContent(
  function waitForText (line 295) | async function waitForText(
  function waitFor (line 323) | async function waitFor(
  function getStdOutput (line 345) | function getStdOutput(
  constant ISLAND_FIXTURE_DIR (line 357) | const ISLAND_FIXTURE_DIR = path.join(import.meta.dirname!, "fixtures_isl...

FILE: packages/init/src/init.ts
  constant FRESH_VERSION (line 8) | const FRESH_VERSION = "2.2.1";
  constant FRESH_TAILWIND_VERSION (line 9) | const FRESH_TAILWIND_VERSION = "1.0.0";
  constant FRESH_VITE_PLUGIN (line 10) | const FRESH_VITE_PLUGIN = "1.0.0";
  constant PREACT_VERSION (line 11) | const PREACT_VERSION = "10.28.3";
  constant PREACT_SIGNALS_VERSION (line 12) | const PREACT_SIGNALS_VERSION = "2.7.1";
  constant TAILWINDCSS_VERSION (line 13) | const TAILWINDCSS_VERSION = "4.1.10";
  constant TAILWINDCSS_POSTCSS_VERSION (line 14) | const TAILWINDCSS_POSTCSS_VERSION = "4.1.10";
  constant POSTCSS_VERSION (line 15) | const POSTCSS_VERSION = "8.5.6";
  function css (line 17) | function css(strs: TemplateStringsArray, ...exprs: string[]): string {
  class InitError (line 29) | class InitError extends Error {}
  function error (line 31) | function error(message: string): never {
  constant HELP_TEXT (line 36) | const HELP_TEXT = `
  constant CONFIRM_EMPTY_MESSAGE (line 68) | const CONFIRM_EMPTY_MESSAGE =
  constant CONFIRM_TAILWIND_MESSAGE (line 70) | const CONFIRM_TAILWIND_MESSAGE = `Set up ${
  constant CONFIRM_VSCODE_MESSAGE (line 73) | const CONFIRM_VSCODE_MESSAGE = `Do you use ${colors.cyan("VS Code")}?`;
  constant CONFIRM_VITE_MESSAGE (line 74) | const CONFIRM_VITE_MESSAGE = `Set up ${
  function initProject (line 78) | async function initProject(
  function writeProjectFile (line 744) | async function writeProjectFile(
  type JsrMeta (line 785) | interface JsrMeta {
  function getLatestVersion (line 792) | async function getLatestVersion(

FILE: packages/init/src/init_test.ts
  function stubPrompt (line 23) | function stubPrompt(result: string) {
  function stubConfirm (line 27) | function stubConfirm(steps: Record<string, boolean> = {}) {
  function stubLogs (line 35) | function stubLogs() {
  function withTmpDir (line 43) | function withTmpDir(): Promise<{ dir: string } & AsyncDisposable> {
  function patchProject (line 52) | async function patchProject(dir: string): Promise<void> {
  function copyRecursive (line 106) | async function copyRecursive(
  function expectProjectFile (line 134) | async function expectProjectFile(dir: string, pathname: string) {
  function expectNotProjectFile (line 142) | async function expectNotProjectFile(dir: string, pathname: string) {
  function readProjectFile (line 156) | async function readProjectFile(dir: string, pathname: string): Promise<s...

FILE: packages/plugin-tailwindcss-v3/src/mod.ts
  type AutoprefixerOptions (line 8) | interface AutoprefixerOptions {
  type TailwindPluginOptions (line 49) | interface TailwindPluginOptions {
  function tailwind (line 53) | function tailwind(
  constant CONFIG_EXTENSIONS (line 74) | const CONFIG_EXTENSIONS = ["ts", "js", "mjs"];
  function findTailwindConfigFile (line 76) | async function findTailwindConfigFile(directory: string): Promise<string> {
  function initTailwind (line 105) | async function initTailwind(

FILE: packages/plugin-tailwindcss/src/mod.ts
  function tailwind (line 9) | function tailwind(

FILE: packages/plugin-tailwindcss/src/types.ts
  type PluginOptions (line 4) | type PluginOptions = {
  type TailwindPluginOptions (line 19) | interface TailwindPluginOptions extends PluginOptions {

FILE: packages/plugin-vite/demo/components/CssModuleNonIsland.tsx
  function CssModulesNonIsland (line 4) | function CssModulesNonIsland() {

FILE: packages/plugin-vite/demo/islands/Bar.tsx
  function Bar (line 3) | function Bar() {

FILE: packages/plugin-vite/demo/islands/CssModules.tsx
  function CssModules (line 6) | function CssModules() {

FILE: packages/plugin-vite/demo/islands/CssModulesOther.tsx
  function CssModulesOther (line 4) | function CssModulesOther() {

FILE: packages/plugin-vite/demo/islands/Foo.tsx
  function Foo (line 3) | function Foo() {

FILE: packages/plugin-vite/demo/islands/IslandNestedInner.tsx
  function IslandNestedInner (line 3) | function IslandNestedInner() {

FILE: packages/plugin-vite/demo/islands/IslandNestedOuter.tsx
  function IslandNestedOuter (line 4) | function IslandNestedOuter() {

FILE: packages/plugin-vite/demo/islands/tests/CounterHooks.tsx
  function CounterHooks (line 3) | function CounterHooks() {

FILE: packages/plugin-vite/demo/islands/tests/EnvIsland.tsx
  function EnvIsland (line 3) | function EnvIsland() {

FILE: packages/plugin-vite/demo/islands/tests/IslandAssets.tsx
  function IslandAssets (line 3) | function IslandAssets() {

FILE: packages/plugin-vite/demo/islands/tests/Mime.tsx
  function MimeIsland (line 4) | function MimeIsland() {

FILE: packages/plugin-vite/demo/islands/tests/Ready.tsx
  function ReadyIsland (line 3) | function ReadyIsland() {

FILE: packages/plugin-vite/demo/routes/about.tsx
  function About (line 8) | function About() {

FILE: packages/plugin-vite/demo/routes/index.tsx
  function Index (line 1) | function Index() {

FILE: packages/plugin-vite/demo/routes/tests/assets.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/commonjs.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/css.tsx
  function Page (line 4) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/css_modules.tsx
  function Page (line 5) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/env.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/feed.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/ioredis.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/island_assets.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/island_hooks.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/island_nested.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/it_works.tsx
  function Page (line 1) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/jsx_namespace.tsx
  function Page (line 1) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/maxmind.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/mime.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/partial.tsx
  function Page (line 4) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/partial_insert.tsx
  function Page (line 4) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/pg.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/qs.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/radix.tsx
  function Page (line 4) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/redis.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/remote_island.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/stripe.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/supabase_pg.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/tailwind.tsx
  function Page (line 1) | function Page() {

FILE: packages/plugin-vite/demo/routes/tests/throw.tsx
  method GET (line 4) | GET() {

FILE: packages/plugin-vite/src/mod.ts
  function fresh (line 56) | function fresh(config?: FreshViteConfig): Plugin[] {
  function loadEnvFile (line 255) | async function loadEnvFile(envPath: string) {

FILE: packages/plugin-vite/src/plugins/build_id.ts
  function buildIdPlugin (line 3) | function buildIdPlugin(): Plugin {
  function getBuildId (line 45) | async function getBuildId(dev: boolean): Promise<string> {

FILE: packages/plugin-vite/src/plugins/client_entry.ts
  function clientEntryPlugin (line 4) | function clientEntryPlugin(options: ResolvedFreshViteConfig): Plugin {

FILE: packages/plugin-vite/src/plugins/client_snapshot.ts
  function clientSnapshot (line 6) | function clientSnapshot(options: ResolvedFreshViteConfig): Plugin[] {
  function isIslandPath (line 161) | function isIslandPath(
  function invalidateSnapshots (line 176) | function invalidateSnapshots(server: ViteDevServer) {

FILE: packages/plugin-vite/src/plugins/deno.ts
  constant BUILTINS (line 18) | const BUILTINS = new Set(builtinModules);
  type DenoState (line 20) | interface DenoState {
  function deno (line 24) | function deno(): Plugin {
  function isJsMediaType (line 281) | function isJsMediaType(media: MediaType): boolean {
  type DenoSpecifier (line 307) | type DenoSpecifier = string & { __deno: string };
  function isDenoSpecifier (line 309) | function isDenoSpecifier(str: unknown): str is DenoSpecifier {
  function toDenoSpecifier (line 313) | function toDenoSpecifier(spec: string, type: RequestedModuleType) {
  function parseDenoSpecifier (line 317) | function parseDenoSpecifier(
  function getDenoType (line 343) | function getDenoType(id: string, type: string): RequestedModuleType {
  function babelTransform (line 359) | function babelTransform(

FILE: packages/plugin-vite/src/plugins/dev_server.ts
  function devServer (line 7) | function devServer(): Plugin[] {
  function collectCss (line 144) | async function collectCss(

FILE: packages/plugin-vite/src/plugins/patches.ts
  function patches (line 13) | function patches(): Plugin {

FILE: packages/plugin-vite/src/plugins/patches/code_eval.ts
  constant APPLY_PG_QUIRKS (line 3) | const APPLY_PG_QUIRKS = "applyPgQuirks";
  function codeEvalPlugin (line 5) | function codeEvalPlugin(
  function evaluateExpr (line 42) | function evaluateExpr(
  function applyBinExpr (line 149) | function applyBinExpr(
  constant PROCESS_PROPERTIES (line 187) | const PROCESS_PROPERTIES = new Set([

FILE: packages/plugin-vite/src/plugins/patches/code_eval_test.ts
  function runTest (line 5) | function runTest(

FILE: packages/plugin-vite/src/plugins/patches/commonjs.ts
  constant BUILTINS (line 4) | const BUILTINS = new Set(builtinModules);
  function cjsPlugin (line 6) | function cjsPlugin(
  function isModuleExports (line 746) | function isModuleExports(
  function getExportsAssignName (line 754) | function getExportsAssignName(
  function isEsModuleFlag (line 773) | function isEsModuleFlag(
  function isObjEsModuleFlag (line 790) | function isObjEsModuleFlag(
  function isNodeBuiltin (line 800) | function isNodeBuiltin(specifier: string): boolean {

FILE: packages/plugin-vite/src/plugins/patches/commonjs_test.ts
  function runTest (line 5) | function runTest(
  constant INIT (line 18) | const INIT = `var exports = {},
  constant DEFAULT_EXPORT (line 32) | const DEFAULT_EXPORT = `const _default = exports.default ?? exports;`;
  constant DEFAULT_EXPORT_END (line 33) | const DEFAULT_EXPORT_END = `export default _default;
  constant IMPORT_REQUIRE (line 35) | const IMPORT_REQUIRE = `import { createRequire } from "node:module";
  constant EXPORT_ES_MODULE (line 37) | const EXPORT_ES_MODULE = `export var __esModule = exports.__esModule;`;

FILE: packages/plugin-vite/src/plugins/patches/http_absolute.ts
  function maybeRewrite (line 9) | function maybeRewrite(
  function httpAbsolute (line 24) | function httpAbsolute(url: URL | null) {

FILE: packages/plugin-vite/src/plugins/patches/http_absolute_test.ts
  function runTest (line 5) | function runTest(options: { input: string; expected: string; url?: URL }) {

FILE: packages/plugin-vite/src/plugins/patches/inline_env_vars.ts
  function inlineEnvVarsPlugin (line 3) | function inlineEnvVarsPlugin(mode: string, env: Record<string, string>) {

FILE: packages/plugin-vite/src/plugins/patches/inline_env_vars_test.ts
  function runTest (line 5) | function runTest(

FILE: packages/plugin-vite/src/plugins/patches/jsx_comment.ts
  function jsxComments (line 3) | function jsxComments(): PluginObj {

FILE: packages/plugin-vite/src/plugins/patches/jsx_comment_test.ts
  function runTest (line 5) | function runTest(options: { input: string; expected: string }) {

FILE: packages/plugin-vite/src/plugins/patches/remove_polyfills.ts
  function removePolyfills (line 3) | function removePolyfills(

FILE: packages/plugin-vite/src/plugins/patches/remove_polyfills_test.ts
  function runTest (line 5) | function runTest(options: { input: string; expected: string }) {

FILE: packages/plugin-vite/src/plugins/server_entry.ts
  function serverEntryPlugin (line 11) | function serverEntryPlugin(

FILE: packages/plugin-vite/src/plugins/server_snapshot.ts
  function serverSnapshot (line 26) | function serverSnapshot(options: ResolvedFreshViteConfig): Plugin[] {
  function walkUp (line 530) | function walkUp(

FILE: packages/plugin-vite/src/plugins/shims.ts
  constant SHIMS (line 4) | const SHIMS: Record<string, string> = {
  function shims (line 19) | function shims(): Plugin {

FILE: packages/plugin-vite/src/plugins/shims/object.entries/index.ts
  function entries (line 2) | function entries(obj: any) {

FILE: packages/plugin-vite/src/plugins/shims/supports-color/index.ts
  type ColorSupport (line 1) | interface ColorSupport {
  function toLevel (line 8) | function toLevel(depth: number): 1 | 2 | 3 {
  function toSupport (line 15) | function toSupport(depth: number): ColorSupport {

FILE: packages/plugin-vite/src/plugins/verify_imports.ts
  type ImportCheckDiagnostic (line 8) | interface ImportCheckDiagnostic {
  type ImportCheck (line 16) | type ImportCheck = (
  type CheckImportOptions (line 21) | interface CheckImportOptions {
  function checkImports (line 25) | function checkImports(pluginOptions: CheckImportOptions): Plugin {
  function findAncestors (line 157) | function findAncestors(

FILE: packages/plugin-vite/src/shared.ts
  function hashCode (line 1) | function hashCode(moduleId: string) {

FILE: packages/plugin-vite/src/utils.ts
  constant JS_REG (line 5) | const JS_REG = /\.([tj]sx?|[mc]?[tj]s)(\?.*)?$/;
  constant JSX_REG (line 6) | const JSX_REG = /\.[tj]sx(\?.*)?$/;
  function pathWithRoot (line 8) | function pathWithRoot(fileOrDir: string, root?: string): string {
  type FreshState (line 20) | interface FreshState {
  type ClientSnapshot (line 34) | interface ClientSnapshot {
  type FreshViteConfig (line 39) | interface FreshViteConfig {
  type ResolvedFreshViteConfig (line 68) | type ResolvedFreshViteConfig =

FILE: packages/plugin-vite/tests/fixtures/deno_global_island/islands/Foo.tsx
  function Foo (line 1) | function Foo() {

FILE: packages/plugin-vite/tests/fixtures/deno_global_island/routes/index.tsx
  function Hello (line 3) | function Hello() {

FILE: packages/plugin-vite/tests/fixtures/deno_global_ssr/routes/index.tsx
  function Hello (line 1) | function Hello() {

FILE: packages/plugin-vite/tests/fixtures/island_global_name/islands/Map.tsx
  function Map (line 4) | function Map() {

FILE: packages/plugin-vite/tests/fixtures/island_global_name/routes/index.tsx
  function Page (line 3) | function Page() {

FILE: packages/plugin-vite/tests/fixtures/no_islands/routes/index.tsx
  function Hello (line 1) | function Hello() {

FILE: packages/plugin-vite/tests/fixtures/no_static/routes/index.tsx
  function Hello (line 1) | function Hello() {

FILE: packages/plugin-vite/tests/fixtures/node_builtin/islands/NodeIsland.tsx
  function NodeIsland (line 3) | function NodeIsland() {

FILE: packages/plugin-vite/tests/fixtures/node_builtin/routes/index.tsx
  function Hello (line 3) | function Hello() {

FILE: packages/plugin-vite/tests/fixtures/remote_island/routes/index.tsx
  function Hello (line 3) | function Hello() {

FILE: packages/plugin-vite/tests/fixtures/tailwind_app/routes/_app.tsx
  function App (line 3) | function App(props: PageProps) {

FILE: packages/plugin-vite/tests/fixtures/tailwind_app/routes/index.tsx
  function Hello (line 1) | function Hello() {

FILE: packages/plugin-vite/tests/fixtures/tailwind_no_app/routes/index.tsx
  function Hello (line 1) | function Hello() {

FILE: packages/plugin-vite/tests/fixtures/test_files_exclusion/routes/index.tsx
  function Home (line 1) | function Home() {

FILE: packages/plugin-vite/tests/fixtures/test_files_exclusion/routes/index_test.tsx
  function TestRoute (line 2) | function TestRoute() {

FILE: packages/plugin-vite/tests/test_utils.ts
  constant DEMO_DIR (line 7) | const DEMO_DIR = path.join(import.meta.dirname!, "..", "demo");
  constant FIXTURE_DIR (line 8) | const FIXTURE_DIR = path.join(import.meta.dirname!, "fixtures");
  function updateFile (line 10) | async function updateFile(
  function copyDir (line 25) | async function copyDir(from: string, to: string) {
  function prepareDevServer (line 50) | async function prepareDevServer(fixtureDir: string) {
  function launchDevServer (line 74) | async function launchDevServer(
  function spawnDevServer (line 89) | async function spawnDevServer(
  function withDevServer (line 125) | async function withDevServer(
  function buildVite (line 134) | async function buildVite(
  function usingEnv (line 173) | function usingEnv(name: string, value: string) {
  type ProdOptions (line 187) | interface ProdOptions {
  function launchProd (line 194) | async function launchProd(

FILE: packages/update/src/mod.ts
  constant MIN_DENO_VERSION (line 7) | const MIN_DENO_VERSION = "1.43.1";
  constant HELP (line 9) | const HELP = `@fresh/update

FILE: packages/update/src/update.ts
  constant FRESH_VERSION (line 9) | const FRESH_VERSION = "2.2.1";
  constant PREACT_VERSION (line 10) | const PREACT_VERSION = "10.28.3";
  constant PREACT_SIGNALS_VERSION (line 11) | const PREACT_SIGNALS_VERSION = "2.7.1";
  constant HIDE_FILES (line 14) | const HIDE_FILES = /[\\/]+(node_modules|vendor)[\\/]+/;
  type DenoJson (line 15) | interface DenoJson {
  function format (line 23) | async function format(filePath: string) {
  function writeFormatted (line 30) | async function writeFormatted(filePath: string, content: string) {
  function updateDenoJson (line 35) | async function updateDenoJson(
  type ImportState (line 66) | interface ImportState {
  function updateProject (line 86) | async function updateProject(dir: string) {
  function updateFile (line 263) | async function updateFile(sourceFile: tsmorph.SourceFile): Promise<boole...
  function removeEmptyImport (line 461) | function removeEmptyImport(d: tsmorph.ImportDeclaration) {
  function maybePrependReqVar (line 471) | function maybePrependReqVar(
  function rewriteCtxMethods (line 573) | function rewriteCtxMethods(
  function rewriteCtxMemberName (line 633) | function rewriteCtxMemberName(

FILE: packages/update/src/update_test.ts
  function readFiles (line 13) | async function readFiles(dir: string): Promise<Record<string, string>> {

FILE: packages/update/src/utils.ts
  function ensureMinDenoVersion (line 6) | function ensureMinDenoVersion(minVersion: string) {
  function error (line 27) | function error(message: string): never {

FILE: tools/check_links.ts
  type CheckLink (line 14) | interface CheckLink {

FILE: tools/release.ts
  function showHelp (line 6) | function showHelp() {
  function exitError (line 13) | function exitError(msg: string): never {
  constant ROOT_DIR (line 26) | const ROOT_DIR = path.join(import.meta.dirname!, "..");
  function formatUpgradeMsg (line 62) | function formatUpgradeMsg(
  function replaceInFile (line 89) | async function replaceInFile(
  function replaceJsonVersion (line 100) | function replaceJsonVersion(version: string) {
  function getNpmVersion (line 107) | async function getNpmVersion(name: string) {
  function updateVersions (line 123) | function updateVersions(content: string): string {
  function replaceDepVersion (line 149) | function replaceDepVersion(

FILE: www/components/CodeBlock.tsx
  function CodeBlock (line 3) | function CodeBlock(

FILE: www/components/CodeWindow.tsx
  type CodeWindowProps (line 3) | interface CodeWindowProps extends JSX.HTMLAttributes<HTMLDivElement> {
  function CodeWindow (line 7) | function CodeWindow(props: CodeWindowProps) {

FILE: www/components/CopyButton.tsx
  function CopyButton (line 3) | function CopyButton(props: { code: string }) {

FILE: www/components/DocsSidebar.tsx
  function SidebarCategory (line 6) | function SidebarCategory(props: {
  function SidebarEntry (line 30) | function SidebarEntry(props: {

FILE: www/components/FancyLink.tsx
  function FancyLink (line 3) | function FancyLink(

FILE: www/components/FeatureIcons.tsx
  function NoBuild (line 1) | function NoBuild() {
  function TypeScript (line 31) | function TypeScript() {
  function Island (line 101) | function Island() {
  function Globe (line 144) | function Globe() {
  function LightWeight (line 165) | function LightWeight() {
  function Garbage (line 209) | function Garbage() {

FILE: www/components/Footer.tsx
  constant LINKS (line 3) | const LINKS = [
  function Footer (line 18) | function Footer(props: JSX.HTMLAttributes<HTMLElement>) {

FILE: www/components/Header.tsx
  function Header (line 3) | function Header(props: { title: string; active: string }) {
  function Logo (line 30) | function Logo() {

FILE: www/components/Icons.tsx
  function IconMinus (line 1) | function IconMinus() {
  function IconPlus (line 21) | function IconPlus() {
  function Leaf (line 41) | function Leaf() {
  function Copy (line 58) | function Copy() {
  function Check (line 76) | function Check() {
  function Info (line 97) | function Info() {
  function GitHub (line 116) | function GitHub(props: { class?: string }) {
  function Discord (line 133) | function Discord(props: { class?: string }) {
  function ArrowRight (line 151) | function ArrowRight() {

FILE: www/components/NavigationBar.tsx
  function NavigationBar (line 4) | function NavigationBar(

FILE: www/components/PageSection.tsx
  function PageSection (line 3) | function PageSection(props: JSX.HTMLAttributes<HTMLDivElement>) {

FILE: www/components/Projects.tsx
  type Project (line 2) | interface Project {
  type ProjectProps (line 9) | interface ProjectProps {
  function Projects (line 14) | function Projects(props: ProjectProps) {

FILE: www/components/SideBySide.tsx
  type ColumnConfiguration (line 3) | type ColumnConfiguration = "1/1" | "2/3" | "3/2";
  type SideBySideProps (line 5) | interface SideBySideProps extends JSX.HTMLAttributes<HTMLDivElement> {
  function SideBySide (line 11) | function SideBySide(props: SideBySideProps) {

FILE: www/components/WaveTank.ts
  type Spring (line 1) | interface Spring {
  class WaveTank (line 6) | class WaveTank {
    method constructor (line 13) | constructor() {
    method update (line 22) | update(springs: Spring[]) {

FILE: www/components/homepage/CTA.tsx
  function CTA (line 3) | function CTA() {

FILE: www/components/homepage/DemoBox.tsx
  type DemoBoxProps (line 3) | interface DemoBoxProps extends JSX.HTMLAttributes<HTMLDivElement> {
  function DemoBox (line 7) | function DemoBox(props: DemoBoxProps) {

FILE: www/components/homepage/DenoSection.tsx
  function DenoSection (line 6) | function DenoSection() {

FILE: www/components/homepage/ExampleArrow.tsx
  function ExampleArrow (line 3) | function ExampleArrow(

FILE: www/components/homepage/FormsSection.tsx
  function FormsSection (line 29) | function FormsSection() {

FILE: www/components/homepage/Hero.tsx
  function Hero (line 6) | function Hero() {
  function CopyArea (line 30) | function CopyArea(props: { code: string }) {

FILE: www/components/homepage/IslandsSection.tsx
  function IslandsSection (line 29) | function IslandsSection() {

FILE: www/components/homepage/PartialsSection.tsx
  function PartialsSection (line 34) | function PartialsSection() {

FILE: www/components/homepage/RenderingSection.tsx
  function RenderingSection (line 16) | function RenderingSection() {

FILE: www/components/homepage/SectionHeading.tsx
  function SectionHeading (line 3) | function SectionHeading(

FILE: www/components/homepage/Simple.tsx
  function Simple (line 3) | function Simple() {

FILE: www/components/homepage/SocialProof.tsx
  function SocialProof (line 5) | function SocialProof() {

FILE: www/data/docs.ts
  type TableOfContentsEntry (line 3) | interface TableOfContentsEntry {
  type TableOfContentsCategory (line 11) | interface TableOfContentsCategory {
  type TableOfContentsCategoryEntry (line 17) | interface TableOfContentsCategoryEntry {
  constant TABLE_OF_CONTENTS (line 22) | const TABLE_OF_CONTENTS: Record<
  constant CATEGORIES (line 26) | const CATEGORIES: Record<string, TableOfContentsCategory[]> = {};
  constant VERSIONS (line 28) | const VERSIONS = Object.keys(toc);
  constant CANARY_VERSION (line 29) | const CANARY_VERSION = toc.canary ? "canary" : "";
  constant LATEST_VERSION (line 30) | const LATEST_VERSION =
  function getFirstPageUrl (line 92) | function getFirstPageUrl(version: string) {

FILE: www/islands/Counter.tsx
  type CounterProps (line 5) | interface CounterProps {
  function Counter (line 9) | function Counter(props: CounterProps) {
  function RoundedButton (line 45) | function RoundedButton(props: JSX.HTMLAttributes<HTMLButtonElement>) {

FILE: www/islands/FormSubmitDemo.tsx
  function FormSubmitDemo (line 1) | function FormSubmitDemo() {

FILE: www/islands/LemonBottom.tsx
  function easeInCirc (line 5) | function easeInCirc(x: number) {
  function LemonBottom (line 11) | function LemonBottom() {

FILE: www/islands/LemonDrop.tsx
  function easeInCirc (line 5) | function easeInCirc(x: number) {
  function LemonDrop (line 11) | function LemonDrop() {

FILE: www/islands/LemonTop.tsx
  function easeInCirc (line 5) | function easeInCirc(x: number) {
  function LemonTop (line 11) | function LemonTop() {

FILE: www/islands/SearchButton.tsx
  type DocSearchProps (line 5) | type DocSearchProps = {
  function SearchButton (line 12) | function SearchButton(

FILE: www/islands/TableOfContents.tsx
  type TableOfContentsProps (line 5) | interface TableOfContentsProps {
  function setActiveLink (line 9) | function setActiveLink(
  function hLevelToClass (line 34) | function hLevelToClass(level: number): string {
  function TableOfContents (line 40) | function TableOfContents({ headings }: TableOfContentsProps) {

FILE: www/islands/ThemeToggle.tsx
  function ThemeToggle (line 4) | function ThemeToggle() {

FILE: www/islands/VersionSelect.tsx
  function VersionSelect (line 6) | function VersionSelect(

FILE: www/routes/_error.tsx
  function ServerCodePage (line 4) | function ServerCodePage(
  function ErrorPage (line 31) | function ErrorPage(props: PageProps) {

FILE: www/routes/_middleware.ts
  constant GA4_MEASUREMENT_ID (line 5) | const GA4_MEASUREMENT_ID = Deno.env.get("GA4_MEASUREMENT_ID");
  function ga4 (line 9) | function ga4<T>(
  function handler (line 90) | async function handler<T>(

FILE: www/routes/docs/[...slug].tsx
  type Data (line 21) | interface Data {
  type NavEntry (line 25) | interface NavEntry {
  type VersionLink (line 31) | interface VersionLink {
  type Page (line 37) | interface Page extends TableOfContentsEntry {
  method GET (line 49) | async GET(ctx) {
  function MobileSidebar (line 258) | function MobileSidebar({ page }: { page: Page }) {
  function ForwardBackButtons (line 295) | function ForwardBackButtons(props: {

FILE: www/routes/docs/_layout.tsx
  function Layout (line 3) | function Layout({ Component }: PageProps) {

FILE: www/routes/docs/_middleware.ts
  constant REDIRECTS (line 3) | const REDIRECTS: Record<string, string> = {
  function handler (line 10) | async function handler<T>(ctx: Context<T>) {

FILE: www/routes/docs/index.tsx
  method GET (line 4) | GET(ctx) {

FILE: www/routes/index.tsx
  method GET (line 18) | GET(ctx) {
  method POST (line 38) | async POST(ctx) {
  function HelloBar (line 73) | function HelloBar() {

FILE: www/routes/raw.ts
  constant BASE_URL (line 7) | const BASE_URL = "https://raw.githubusercontent.com/denoland/fresh/";
  method GET (line 20) | async GET(ctx) {

FILE: www/routes/recipes/_layout.tsx
  function Layout (line 4) | function Layout({ Component }: PageProps) {

FILE: www/routes/showcase-bak.tsx
  constant TITLE (line 9) | const TITLE = "Showcase | Fresh";
  constant DESCRIPTION (line 10) | const DESCRIPTION = "Selection of projects that have been built with Fre...
  method GET (line 13) | GET(ctx) {
  function Showcase (line 77) | function Showcase({ items }: { items: Project[] }) {

FILE: www/routes/showcase.tsx
  constant TITLE (line 9) | const TITLE = "Showcase | Fresh";
  constant DESCRIPTION (line 10) | const DESCRIPTION = "Selection of projects that have been built with Fre...
  method GET (line 13) | GET(ctx) {
  function Showcase (line 77) | function Showcase({ items }: { items: Project[] }) {

FILE: www/routes/thanks.tsx
  method GET (line 7) | GET(ctx) {

FILE: www/routes/update.tsx
  method GET (line 5) | GET({ req }) {

FILE: www/utils/markdown.ts
  constant ADMISSION_REG (line 13) | const ADMISSION_REG = /^\[(info|warn|tip)\]:\s/;
  constant LOGOS (line 15) | const LOGOS = [
  type MarkdownHeading (line 78) | interface MarkdownHeading {
  class DefaultRenderer (line 84) | class DefaultRenderer extends Marked.Renderer {
    method text (line 88) | override text(
    method heading (line 110) | override heading({ tokens, depth }: Marked.Tokens.Heading): string {
    method link (line 144) | override link({ href, title, tokens }: Marked.Tokens.Link) {
    method image (line 154) | override image({ href, text, title }: Marked.Tokens.Image) {
    method code (line 158) | override code({ lang: info, text }: Marked.Tokens.Code): string {
    method blockquote (line 249) | override blockquote({ text, tokens }: Marked.Tokens.Blockquote): string {
    method #assert (line 272) | #assert(expr: unknown, msg: string): asserts expr {
  type MarkdownOptions (line 277) | interface MarkdownOptions {
  function renderMarkdown (line 280) | function renderMarkdown(

FILE: www/utils/screenshot.ts
  function validateArgs (line 4) | function validateArgs(args: string[]): [string, string] {
  function validateUrl (line 11) | function validateUrl(url: string): URL {
  function generateFilePaths (line 19) | function generateFilePaths(
  function captureScreenshot (line 28) | async function captureScreenshot(

FILE: www/utils/state.ts
  type State (line 3) | interface State {

FILE: www/vite.config.ts
  function copyDocs (line 18) | function copyDocs(): Plugin {
Condensed preview — 485 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,463K chars).
[
  {
    "path": ".gitattributes",
    "chars": 61,
    "preview": "# Use Unix line endings in all text files.\n* text=auto eol=lf"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "chars": 5215,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 136,
    "preview": "# Contributing Guidelines\n\n## Submitting a pull request\n\nFirst, please be sure to ensure `deno task ok` is run and succe"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 173,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      # Check for updates t"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 1511,
    "preview": "name: ci\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  test:\n    runs-on: ${{ matrix.o"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "chars": 867,
    "preview": "name: Deploy\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  deploy:\n    name: Deploy\n   "
  },
  {
    "path": ".github/workflows/post_publish.yml",
    "chars": 924,
    "preview": "name: post_publish\n\non:\n  release:\n    types: [published]\n\njobs:\n  update-dl-version:\n    name: update dl.deno.land vers"
  },
  {
    "path": ".github/workflows/publish.yml",
    "chars": 500,
    "preview": "name: Publish JSR\n\non:\n  push:\n    branches:\n      - main\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    permissions:\n"
  },
  {
    "path": ".gitignore",
    "chars": 109,
    "preview": "_fresh/\n.vite/\nvendor/\nnode_modules/\n.docs/\n.DS_Store\ntmp_*\ncoverage/\nvite-inspect/\n.vite-inspect/\ndemo/dist/"
  },
  {
    "path": ".vscode/extensions.json",
    "chars": 58,
    "preview": "{\n  \"recommendations\": [\n    \"denoland.vscode-deno\"\n  ]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 729,
    "preview": "{\n  \"deno.enable\": true,\n  \"deno.lint\": true,\n  \"deno.codeLens.test\": true,\n  \"deno.documentPreloadLimit\": 2000,\n  \"edit"
  },
  {
    "path": ".vscode/tailwind.json",
    "chars": 2295,
    "preview": "{\n  \"version\": 1.1,\n  \"atDirectives\": [\n    {\n      \"name\": \"@tailwind\",\n      \"description\": \"Use the `@tailwind` direc"
  },
  {
    "path": "LICENSE",
    "chars": 1075,
    "preview": "MIT License\n\nCopyright (c) 2021-2023 Luca Casonato\n\nPermission is hereby granted, free of charge, to any person obtainin"
  },
  {
    "path": "README.md",
    "chars": 3508,
    "preview": "[Documentation](#-documentation) | [Getting started](#-getting-started) |\n[API Reference](https://deno.land/x/fresh?doc)"
  },
  {
    "path": "_typos.toml",
    "chars": 292,
    "preview": "[files]\nextend-exclude = [\n  \"packages/fresh/tests/fixture_partials/routes/scroll_restoration/index.tsx\",\n  \"www/static/"
  },
  {
    "path": "deno.json",
    "chars": 4300,
    "preview": "{\n  \"vendor\": true,\n  \"nodeModulesDir\": \"manual\",\n  \"workspace\": [\n    \"./packages/*\",\n    \"./www\"\n  ],\n  \"tasks\": {\n   "
  },
  {
    "path": "docs/1.x/concepts/ahead-of-time-builds.md",
    "chars": 3313,
    "preview": "---\ndescription: |\n  Fresh optimize assets ahead of time, which makes pages load way quicker.\n---\n\nFresh enables you to "
  },
  {
    "path": "docs/1.x/concepts/app-wrapper.md",
    "chars": 2844,
    "preview": "---\ndescription: |\n  Add a global app wrapper to provide common meta tags or context for application routes.\n---\n\nAn app"
  },
  {
    "path": "docs/1.x/concepts/architecture.md",
    "chars": 1304,
    "preview": "---\ndescription: |\n  Fresh's architecture is designed to make it easy to build fast, scalable, and reliable applications"
  },
  {
    "path": "docs/1.x/concepts/data-fetching.md",
    "chars": 2019,
    "preview": "---\ndescription: |\n  Data fetching in Fresh happens inside of route handler functions. These can pass route data to the "
  },
  {
    "path": "docs/1.x/concepts/deployment.md",
    "chars": 2835,
    "preview": "---\ndescription: |\n  Fresh can be deployed to a variety of platforms easily.\n---\n\nWhile Fresh is designed to be deployed"
  },
  {
    "path": "docs/1.x/concepts/error-pages.md",
    "chars": 2389,
    "preview": "---\ndescription: |\n  Error pages can be used to customize the page that is shown when an error occurs in the application"
  },
  {
    "path": "docs/1.x/concepts/forms.md",
    "chars": 3161,
    "preview": "---\ndescription: |\n  Robustly handle user inputs using HTML `<form>` elements client side, and form\n  submission handler"
  },
  {
    "path": "docs/1.x/concepts/index.md",
    "chars": 285,
    "preview": "---\ndescription: |\n  This chapter goes over some fundamental concepts of Fresh.\n---\n\nThis chapter goes over some fundame"
  },
  {
    "path": "docs/1.x/concepts/islands.md",
    "chars": 6649,
    "preview": "---\ndescription: |\n  Islands enable client side interactivity in Fresh. They are hydrated on the client in addition to b"
  },
  {
    "path": "docs/1.x/concepts/layouts.md",
    "chars": 3203,
    "preview": "---\ndescription: |\n  Add a layout to provide common meta tags, context for application sub routes, and common layout.\n--"
  },
  {
    "path": "docs/1.x/concepts/middleware.md",
    "chars": 6947,
    "preview": "---\ndescription: |\n  Add middleware routes to intercept requests or responses for analytics purposes, access control, or"
  },
  {
    "path": "docs/1.x/concepts/partials.md",
    "chars": 7762,
    "preview": "---\ndescription: |\n  Partials allow areas of a page to be updated without causing the browser to reload the page. They e"
  },
  {
    "path": "docs/1.x/concepts/plugins.md",
    "chars": 9003,
    "preview": "---\ndescription: Plugins can add new functionality to Fresh without requiring significant complexity.\n---\n\nPlugins can d"
  },
  {
    "path": "docs/1.x/concepts/routes.md",
    "chars": 5924,
    "preview": "---\ndescription: |\n  Routes are the basic building block of Fresh applications. They are used to define the behaviour th"
  },
  {
    "path": "docs/1.x/concepts/routing.md",
    "chars": 5704,
    "preview": "---\ndescription: |\n  File based routing is the simplest way to do routing in Fresh apps. Additionally custom patterns ca"
  },
  {
    "path": "docs/1.x/concepts/server-components.md",
    "chars": 824,
    "preview": "---\ndescription: |\n  Fresh's architecture is designed to leverage server components by default.\n---\n\nIf you've read abou"
  },
  {
    "path": "docs/1.x/concepts/server-configuration.md",
    "chars": 5579,
    "preview": "---\ndescription: |\n  The ability to configure the core Fresh server leads to its flexibility.\n---\n\nIn this page we discu"
  },
  {
    "path": "docs/1.x/concepts/static-files.md",
    "chars": 2023,
    "preview": "---\ndescription: |\n  Fresh has built-in support for serving static files. This is useful for serving images, CSS, and ot"
  },
  {
    "path": "docs/1.x/concepts/updating.md",
    "chars": 4786,
    "preview": "---\ndescription: |\n  New versions of Fresh are regularly released. This page explains how to update your project.\n---\n\nF"
  },
  {
    "path": "docs/1.x/examples/active-links.md",
    "chars": 2089,
    "preview": "---\ndescription: |\n  Style active links with ease in Fresh\n---\n\nFresh automatically enhances the accessibility of `<a>` "
  },
  {
    "path": "docs/1.x/examples/authentication-with-supabase.md",
    "chars": 9008,
    "preview": "---\ndescription: |\n  Learn how to implement the PKCE authentication flow using Supabase.\n---\n\nFresh is a great tool for "
  },
  {
    "path": "docs/1.x/examples/changing-the-src-dir.md",
    "chars": 1716,
    "preview": "---\ndescription: |\n  Change the source directory to effectively manage your project.\n---\n\nWhen you initialize a project "
  },
  {
    "path": "docs/1.x/examples/client-side-components-and-libraries.md",
    "chars": 6420,
    "preview": "---\ndescription: |\n  Client side components and libraries\n---\n\nSome components depend on client environments, browser-sp"
  },
  {
    "path": "docs/1.x/examples/creating-a-crud-api.md",
    "chars": 7011,
    "preview": "---\ndescription: |\n  Use HTTP CRUD methods to perform operations on resources. Learn how to use HTTP handlers to create "
  },
  {
    "path": "docs/1.x/examples/dealing-with-cors.md",
    "chars": 2925,
    "preview": "---\ndescription: |\n  CORS enabling routes in your Fresh project.\n---\n\nSo you've encountered some CORS problems and are o"
  },
  {
    "path": "docs/1.x/examples/handling-complex-routes.md",
    "chars": 2155,
    "preview": "---\ndescription: |\n  Sometimes URL based routing isn't enough.\n---\n\nThe page on [routing](/docs/1.x/concepts/routing) hi"
  },
  {
    "path": "docs/1.x/examples/index.md",
    "chars": 1111,
    "preview": "---\ndescription: |\n  In this chapter of the Fresh documentation, you can find examples of features that you may like in "
  },
  {
    "path": "docs/1.x/examples/init-the-server.md",
    "chars": 3494,
    "preview": "---\ndescription: |\n  For when you have some complicated setup that needs to be performed once.\n---\n\nLet's pretend you've"
  },
  {
    "path": "docs/1.x/examples/migrating-to-tailwind.md",
    "chars": 5780,
    "preview": "---\ndescription: |\n  Migrating from twind to Tailwind CSS\n---\n\nStarting with version 1.6 Fresh comes with a proper Tailw"
  },
  {
    "path": "docs/1.x/examples/modifying-the-head.md",
    "chars": 2220,
    "preview": "---\ndescription: |\n  Add components like <title> or <meta> to a <head> tag using Fresh's <Head> component.\n---\n\nWe can u"
  },
  {
    "path": "docs/1.x/examples/rendering-markdown.md",
    "chars": 2405,
    "preview": "---\ndescription: |\n  How to render markdown on your Fresh site.\n---\n\nWhat if you want to render some markdown on your si"
  },
  {
    "path": "docs/1.x/examples/rendering-raw-html.md",
    "chars": 2025,
    "preview": "---\ndescription: |\n  How to render raw HTML in Fresh.\n---\n\nText content in Fresh is always escaped, whether serverside r"
  },
  {
    "path": "docs/1.x/examples/setting-the-language.md",
    "chars": 1419,
    "preview": "---\ndescription: |\n  Set the lang attribute in the <html> tag.\n---\n\nWhen you initialize a project with `deno run -A -r h"
  },
  {
    "path": "docs/1.x/examples/sharing-state-between-islands.md",
    "chars": 4831,
    "preview": "---\ndescription: |\n  When you need to have state shared between islands, this page provides a few recipes.\n---\n\nAll of t"
  },
  {
    "path": "docs/1.x/examples/using-csp.md",
    "chars": 10423,
    "preview": "---\ndescription: |\n  Change the source directory to effectively manage your project.\n---\n\nAs per the\n[MDN documentation]"
  },
  {
    "path": "docs/1.x/examples/using-fresh-canary-version.md",
    "chars": 1792,
    "preview": "---\ndescription: |\n  For cases where the latest release doesn't fit your needs.\n---\n\nPretend you have a use case where y"
  },
  {
    "path": "docs/1.x/examples/using-twind-v1.md",
    "chars": 1880,
    "preview": "---\ndescription: |\n  With a few tweaks one can use twind v1\n---\n\nWhen you initialize a project with `deno run -A -r http"
  },
  {
    "path": "docs/1.x/examples/writing-tests.md",
    "chars": 3178,
    "preview": "---\ndescription: |\n  You can write HTTP tests for your Fresh project by creating an application handler.\n---\n\nYou can wr"
  },
  {
    "path": "docs/1.x/getting-started/adding-interactivity.md",
    "chars": 3497,
    "preview": "---\ndescription: |\n  Add JavaScript based interactivity to your project without sacrificing user\n  experience, by using "
  },
  {
    "path": "docs/1.x/getting-started/create-a-project.md",
    "chars": 2737,
    "preview": "---\ndescription: |\n  Create a new Fresh project by running the Fresh project creation tool. This\n  scaffolds out the var"
  },
  {
    "path": "docs/1.x/getting-started/create-a-route.md",
    "chars": 2521,
    "preview": "---\ndescription: |\n  Create a new route to a Fresh project by creating a new file in the `routes/`\n  folder.\n---\n\nAfter "
  },
  {
    "path": "docs/1.x/getting-started/custom-handlers.md",
    "chars": 2321,
    "preview": "---\ndescription: |\n  Add custom handlers to a route to customize HTTP headers, implement API\n  routes, do data fetching "
  },
  {
    "path": "docs/1.x/getting-started/deploy-to-production.md",
    "chars": 1624,
    "preview": "---\ndescription: |\n  Deploy a Fresh application to Deno Deploy in seconds, making it available on\n  the edge globally - "
  },
  {
    "path": "docs/1.x/getting-started/dynamic-routes.md",
    "chars": 2067,
    "preview": "---\ndescription: |\n  Create a dynamic route in Fresh by adding a dynamic segment to the route name\n  in the routes' file"
  },
  {
    "path": "docs/1.x/getting-started/form-submissions.md",
    "chars": 2857,
    "preview": "---\ndescription: |\n  Robustly handle user inputs using HTML `<form>` elements client side, and form\n  submission handler"
  },
  {
    "path": "docs/1.x/getting-started/index.md",
    "chars": 754,
    "preview": "---\ndescription: |\n  In this chapter of the Fresh documentation, you'll be introduced to the\n  framework. Create a new p"
  },
  {
    "path": "docs/1.x/getting-started/running-locally.md",
    "chars": 2482,
    "preview": "---\ndescription: |\n  To start a Fresh project, just run `deno task start`. This will start the\n  project with default pe"
  },
  {
    "path": "docs/1.x/integrations/index.md",
    "chars": 1140,
    "preview": "---\ndescription: |\n  Various projects can integrate into Fresh to easily add functionality to your\n  project.\n---\n\nThis "
  },
  {
    "path": "docs/1.x/introduction/index.md",
    "chars": 1454,
    "preview": "---\ndescription: |\n  Fresh is a full stack modern web framework for JavaScript and TypeScript\n  developers, designed to "
  },
  {
    "path": "docs/canary/the-canary-version/index.md",
    "chars": 671,
    "preview": "---\ndescription: |\n  Learn more about Fresh canary releases\n---\n\nThe canary version represents the current development s"
  },
  {
    "path": "docs/latest/advanced/app-wrapper.md",
    "chars": 893,
    "preview": "---\ndescription: |\n  Add a global app wrapper to provide common meta tags or context for application routes.\n---\n\nThe ap"
  },
  {
    "path": "docs/latest/advanced/builder.md",
    "chars": 5219,
    "preview": "---\ndescription: |\n  The Builder class is used to generate optimized assets for production.\n---\n\n> [warn]: The `Builder`"
  },
  {
    "path": "docs/latest/advanced/define.md",
    "chars": 2008,
    "preview": "---\ndescription: |\n  Define helpers are a less TypeScripty way to declare middlewares, routes and layouts\n---\n\nDefine he"
  },
  {
    "path": "docs/latest/advanced/environment-variables.md",
    "chars": 1556,
    "preview": "---\ndescription: |\n  Error pages can be used to customize the page that is shown when an error occurs in the application"
  },
  {
    "path": "docs/latest/advanced/error-handling.md",
    "chars": 2701,
    "preview": "---\ndescription: |\n  Error pages can be used to customize the page that is shown when an error occurs in the application"
  },
  {
    "path": "docs/latest/advanced/forms.md",
    "chars": 3069,
    "preview": "---\ndescription: |\n  Robustly handle user inputs using HTML `<form>` elements client side, and form\n  submission handler"
  },
  {
    "path": "docs/latest/advanced/head.md",
    "chars": 2305,
    "preview": "---\ndescription: Modify the document head in Fresh\n---\n\nThe\n[`<head>`](https://developer.mozilla.org/en-US/docs/Web/HTML"
  },
  {
    "path": "docs/latest/advanced/index.md",
    "chars": 159,
    "preview": "---\ndescription: |\n  This chapter goes over some advanced concepts of Fresh.\n---\n\nThis section of the documentation desc"
  },
  {
    "path": "docs/latest/advanced/layouts.md",
    "chars": 1134,
    "preview": "---\ndescription: \"Create re-usable layouts across routes\"\n---\n\nLayouts are plain Preact components that are inherited ba"
  },
  {
    "path": "docs/latest/advanced/partials.md",
    "chars": 7753,
    "preview": "---\ndescription: |\n  Partials allow areas of a page to be updated without causing the browser to reload the page. They e"
  },
  {
    "path": "docs/latest/advanced/troubleshooting.md",
    "chars": 3598,
    "preview": "---\ndescription: |\n  Troubleshooting Fresh applications.\n---\n\nThis site contains some tips to troubleshoot your app in c"
  },
  {
    "path": "docs/latest/advanced/vite.md",
    "chars": 1017,
    "preview": "---\ndescription: |\n  Configure the fresh vite plugin.\n---\n\nThe Fresh vite plugin can be optionally configured in the fol"
  },
  {
    "path": "docs/latest/concepts/app.md",
    "chars": 7217,
    "preview": "---\ndescription: |\n  Add a global app wrapper to provide common meta tags or context for application routes.\n---\n\nThe `A"
  },
  {
    "path": "docs/latest/concepts/context.md",
    "chars": 2805,
    "preview": "---\ndescription: Plugins can add new functionality to Fresh without requiring significant complexity.\n---\n\nThe `Context`"
  },
  {
    "path": "docs/latest/concepts/file-routing.md",
    "chars": 5296,
    "preview": "---\ndescription: |\n  Routes are the basic building block of Fresh applications. They are used to define the behaviour th"
  },
  {
    "path": "docs/latest/concepts/index.md",
    "chars": 1624,
    "preview": "---\ndescription: |\n  This chapter goes over some fundamental concepts of Fresh.\n---\n\nThe way Fresh works is that it rece"
  },
  {
    "path": "docs/latest/concepts/islands.md",
    "chars": 3788,
    "preview": "---\ndescription: |\n  Islands enable client side interactivity in Fresh. They are hydrated on the client in addition to b"
  },
  {
    "path": "docs/latest/concepts/layouts.md",
    "chars": 2724,
    "preview": "---\ndescription: |\n  Add a layout to provide common meta tags, context for application sub routes, and common layout.\n--"
  },
  {
    "path": "docs/latest/concepts/middleware.md",
    "chars": 2469,
    "preview": "---\ndescription: |\n  Add middleware routes to intercept requests or responses for analytics purposes, access control, or"
  },
  {
    "path": "docs/latest/concepts/routing.md",
    "chars": 1135,
    "preview": "---\ndescription: |\n  File based routing is the simplest way to do routing in Fresh apps. Additionally custom patterns ca"
  },
  {
    "path": "docs/latest/concepts/static-files.md",
    "chars": 1401,
    "preview": "---\ndescription: |\n  Fresh has built-in support for serving static files. This is useful for serving images, CSS, and ot"
  },
  {
    "path": "docs/latest/deployment/cloudflare-workers.md",
    "chars": 1041,
    "preview": "---\ndescription: \"Deploy Fresh on Cloudflare Workers\"\n---\n\nDeploy Fresh to Cloudflare Workers by following these instruc"
  },
  {
    "path": "docs/latest/deployment/deno-compile.md",
    "chars": 710,
    "preview": "---\ndescription: \"Generate a self contained executable with deno compile.\"\n---\n\nYou can create a self-contained executab"
  },
  {
    "path": "docs/latest/deployment/deno-deploy.md",
    "chars": 553,
    "preview": "---\ndescription: \"Deploy Fresh on Deno Deploy\"\n---\n\nThe recommended way to deploy Fresh is by using\n[Deno Deploy](https:"
  },
  {
    "path": "docs/latest/deployment/docker.md",
    "chars": 1614,
    "preview": "---\ndescription: \"Deploy Fresh with Docker\"\n---\n\nYou can deploy Fresh to any platform that can run Docker containers. Do"
  },
  {
    "path": "docs/latest/deployment/index.md",
    "chars": 809,
    "preview": "---\ndescription: \"Create a production build of your app\"\n---\n\nWhen shipping an app to production, we can run a build ste"
  },
  {
    "path": "docs/latest/examples/active-links.md",
    "chars": 1370,
    "preview": "---\ndescription: |\n  Style active links with ease in Fresh\n---\n\nFresh automatically enhances the accessibility of `<a>` "
  },
  {
    "path": "docs/latest/examples/daisyui.md",
    "chars": 1506,
    "preview": "---\ntitle: Install daisyUI for Deno Fresh\ndesc: How to install Tailwind CSS and daisyUI in a Deno Fresh project\n---\n\n[da"
  },
  {
    "path": "docs/latest/examples/markdown.md",
    "chars": 1412,
    "preview": "---\ndescription: |\n  How to render markdown on your Fresh site.\n---\n\n[Markdown](https://www.markdownguide.org/basic-synt"
  },
  {
    "path": "docs/latest/examples/migration-guide.md",
    "chars": 9016,
    "preview": "---\ndescription: |\n  Migration guide for Fresh 2.x\n---\n\nWe tried to keep breaking changes in Fresh 2 as minimal as possi"
  },
  {
    "path": "docs/latest/examples/rendering-raw-html.md",
    "chars": 910,
    "preview": "---\ndescription: |\n  How to render raw HTML in Fresh.\n---\n\nText content in Fresh is always escaped, whether serverside r"
  },
  {
    "path": "docs/latest/examples/sharing-state-between-islands.md",
    "chars": 4831,
    "preview": "---\ndescription: |\n  When you need to have state shared between islands, this page provides a few recipes.\n---\n\nAll of t"
  },
  {
    "path": "docs/latest/getting-started/index.md",
    "chars": 4051,
    "preview": "---\ndescription: |\n  In this chapter of the Fresh documentation, you'll be introduced to the\n  framework. Create a new p"
  },
  {
    "path": "docs/latest/introduction/index.md",
    "chars": 2321,
    "preview": "---\ndescription: |\n  Fresh is a full stack modern web framework for JavaScript and TypeScript\n  developers, designed to "
  },
  {
    "path": "docs/latest/plugins/cors.md",
    "chars": 853,
    "preview": "---\ndescription: \"Set CORS HTTP headers with the cors middleware\"\n---\n\nThe `cors()` middleware can be used to add\n[Cross"
  },
  {
    "path": "docs/latest/plugins/csp.md",
    "chars": 947,
    "preview": "---\ndescription: \"Set Content-Security-Policy (CSP) HTTP headers with the csp middleware\"\n---\n\nThe `csp()` middleware ca"
  },
  {
    "path": "docs/latest/plugins/csrf.md",
    "chars": 1112,
    "preview": "---\ndescription: \"Prevent Cross-Site Request Forgery with this middleware\"\n---\n\nThe `csrf()` middleware can be used to a"
  },
  {
    "path": "docs/latest/plugins/index.md",
    "chars": 695,
    "preview": "---\ndescription: \"Extend fresh with plugins\"\n---\n\nFresh itself can be extended through the methods available on the\n[`Ap"
  },
  {
    "path": "docs/latest/plugins/trailing-slashes.md",
    "chars": 611,
    "preview": "---\ndescription: \"Ensure URLs always end or never end with trailing slashes\"\n---\n\nThe `trailingSlashes()` middleware can"
  },
  {
    "path": "docs/latest/testing/index.md",
    "chars": 7082,
    "preview": "---\ndescription: |\n  Learn how to test Fresh applications using Deno's built-in test runner.\n---\n\nTo ensure that your ap"
  },
  {
    "path": "docs/toc.ts",
    "chars": 5822,
    "preview": "import FRESH_VERSIONS_1x from \"../versions.json\" with { type: \"json\" };\nimport LATEST_VERSION_2 from \"../packages/fresh/"
  },
  {
    "path": "packages/build-id/README.md",
    "chars": 87,
    "preview": "# Fresh build id\n\nDon't use this package directly. It's considered internal for Fresh.\n"
  },
  {
    "path": "packages/build-id/deno.json",
    "chars": 183,
    "preview": "{\n  \"name\": \"@fresh/build-id\",\n  \"version\": \"1.0.1\",\n  \"license\": \"MIT\",\n  \"exports\": {\n    \".\": \"./mod.ts\"\n  },\n  \"impo"
  },
  {
    "path": "packages/build-id/mod.ts",
    "chars": 795,
    "preview": "/**\n * Don't use this package directly. It's considered internal for Fresh.\n *\n * @example\n * ```ts\n * // `BUILD_ID` is "
  },
  {
    "path": "packages/examples/LICENSE",
    "chars": 1078,
    "preview": "MIT License\n\nCopyright (c) 2021-2024 the Deno authors\n\nPermission is hereby granted, free of charge, to any person obtai"
  },
  {
    "path": "packages/examples/README.md",
    "chars": 991,
    "preview": "# Examples for Fresh\n\nThis package contains examples for using Fresh with [JSR](https://jsr.io/).\n\nLearn more about the "
  },
  {
    "path": "packages/examples/deno.json",
    "chars": 341,
    "preview": "{\n  \"name\": \"@fresh/examples\",\n  \"version\": \"1.0.1\",\n  \"license\": \"MIT\",\n  \"imports\": {\n    \"fresh\": \"jsr:@fresh/core@^2"
  },
  {
    "path": "packages/examples/src/app1.tsx",
    "chars": 364,
    "preview": "/**\n * Module containing a simple example Fresh App\n *\n * @module\n */\n\nimport { App } from \"fresh\";\nimport { Doc } from "
  },
  {
    "path": "packages/examples/src/app2.tsx",
    "chars": 364,
    "preview": "/**\n * Module containing a simple example Fresh App\n *\n * @module\n */\n\nimport { App } from \"fresh\";\nimport { Doc } from "
  },
  {
    "path": "packages/examples/src/island.tsx",
    "chars": 856,
    "preview": "/**\n * Example of external Fresh Island component.\n *\n * @example\n * ```tsx\n * import { App } from \"fresh\";\n * import { "
  },
  {
    "path": "packages/examples/src/shared.tsx",
    "chars": 288,
    "preview": "import type { ComponentChildren } from \"preact\";\n\nexport function Doc(props: { children?: ComponentChildren }) {\n  retur"
  },
  {
    "path": "packages/fresh/README.md",
    "chars": 759,
    "preview": "# Fresh\n\nFresh is a small, fast and extensible full stack web framework built on Web\nStandards. It’s designed for buildi"
  },
  {
    "path": "packages/fresh/deno.json",
    "chars": 1146,
    "preview": "{\n  \"name\": \"@fresh/core\",\n  \"version\": \"2.2.1\",\n  \"license\": \"MIT\",\n  \"exports\": {\n    \".\": \"./src/mod.ts\",\n    \"./runt"
  },
  {
    "path": "packages/fresh/src/app.ts",
    "chars": 13668,
    "preview": "import { trace } from \"@opentelemetry/api\";\n\nimport { DENO_DEPLOYMENT_ID } from \"@fresh/build-id\";\nimport * as colors fr"
  },
  {
    "path": "packages/fresh/src/app_test.tsx",
    "chars": 26811,
    "preview": "import { expect } from \"@std/expect\";\nimport { App } from \"./app.ts\";\nimport { FakeServer } from \"./test_utils.ts\";\nimpo"
  },
  {
    "path": "packages/fresh/src/build_cache.ts",
    "chars": 3005,
    "preview": "import * as path from \"@std/path\";\nimport type { Command } from \"./commands.ts\";\nimport { fsItemsToCommands, type FsRout"
  },
  {
    "path": "packages/fresh/src/commands.ts",
    "chars": 10065,
    "preview": "import { setAdditionalStyles } from \"./context.ts\";\nimport { HttpError } from \"./error.ts\";\nimport { isHandlerByMethod, "
  },
  {
    "path": "packages/fresh/src/compat.ts",
    "chars": 1875,
    "preview": "import type { ComponentChildren } from \"preact\";\nimport type { Context } from \"./context.ts\";\nimport type { PageProps } "
  },
  {
    "path": "packages/fresh/src/compat_test.tsx",
    "chars": 719,
    "preview": "import type { PageProps } from \"./render.ts\";\nimport { assertType, type IsExact } from \"@std/testing/types\";\nimport { ex"
  },
  {
    "path": "packages/fresh/src/config.ts",
    "chars": 1071,
    "preview": "import * as path from \"@std/path\";\n\nexport interface FreshConfig {\n  /**\n   * Serve fresh from a base path instead of fr"
  },
  {
    "path": "packages/fresh/src/config_test.ts",
    "chars": 649,
    "preview": "import { expect } from \"@std/expect\";\nimport { parseDirPath } from \"./config.ts\";\n\nDeno.test(\"parseDirPath\", () => {\n  c"
  },
  {
    "path": "packages/fresh/src/constants.ts",
    "chars": 532,
    "preview": "export const INTERNAL_PREFIX = \"/_frsh\";\nexport const DEV_ERROR_OVERLAY_URL = `${INTERNAL_PREFIX}/error_overlay`;\nexport"
  },
  {
    "path": "packages/fresh/src/context.ts",
    "chars": 13011,
    "preview": "import {\n  type AnyComponent,\n  type ComponentType,\n  Fragment,\n  type FunctionComponent,\n  h,\n  isValidElement,\n  type "
  },
  {
    "path": "packages/fresh/src/context_test.tsx",
    "chars": 5792,
    "preview": "import { expect } from \"@std/expect\";\nimport { Context } from \"./context.ts\";\nimport { App } from \"fresh\";\nimport { asse"
  },
  {
    "path": "packages/fresh/src/define.ts",
    "chars": 6940,
    "preview": "import type { AnyComponent } from \"preact\";\nimport type { HandlerByMethod, HandlerFn, RouteHandler } from \"./handlers.ts"
  },
  {
    "path": "packages/fresh/src/define_test.ts",
    "chars": 1120,
    "preview": "import { expect } from \"@std/expect\";\nimport { createDefine } from \"./define.ts\";\nimport { page } from \"./handlers.ts\";\n"
  },
  {
    "path": "packages/fresh/src/dev/builder.ts",
    "chars": 11525,
    "preview": "import { App, type ListenOptions, setBuildCache } from \"../app.ts\";\nimport { fsAdapter } from \"../fs.ts\";\nimport * as pa"
  },
  {
    "path": "packages/fresh/src/dev/builder_test.ts",
    "chars": 26602,
    "preview": "import { expect, fn } from \"@std/expect\";\nimport * as path from \"@std/path\";\nimport { Builder, specToName } from \"./buil"
  },
  {
    "path": "packages/fresh/src/dev/check.ts",
    "chars": 2367,
    "preview": "import * as JSONC from \"@std/jsonc\";\nimport * as path from \"@std/path\";\n\nexport interface DenoConfig {\n  workspace?: str"
  },
  {
    "path": "packages/fresh/src/dev/dev_build_cache.ts",
    "chars": 16362,
    "preview": "import {\n  type BuildCache,\n  IslandPreparer,\n  type StaticFile,\n} from \"../build_cache.ts\";\nimport * as path from \"@std"
  },
  {
    "path": "packages/fresh/src/dev/dev_build_cache_test.ts",
    "chars": 1677,
    "preview": "import { expect } from \"@std/expect\";\nimport { MemoryBuildCache } from \"./dev_build_cache.ts\";\nimport { FileTransformer "
  },
  {
    "path": "packages/fresh/src/dev/esbuild.ts",
    "chars": 6327,
    "preview": "import { denoPlugin } from \"@deno/esbuild-plugin\";\nimport type { BuildOptions, Plugin as EsbuildPlugin } from \"esbuild\";"
  },
  {
    "path": "packages/fresh/src/dev/file_transformer.ts",
    "chars": 7307,
    "preview": "import { globToRegExp, isGlob } from \"@std/path\";\nimport type { FsAdapter } from \"../fs.ts\";\nimport { BUILD_ID } from \"@"
  },
  {
    "path": "packages/fresh/src/dev/file_transformer_test.ts",
    "chars": 6834,
    "preview": "import { expect } from \"@std/expect\";\nimport type { FsAdapter } from \"../fs.ts\";\nimport { FileTransformer, type Processe"
  },
  {
    "path": "packages/fresh/src/dev/fs_crawl.ts",
    "chars": 4009,
    "preview": "import { type FsAdapter, fsAdapter } from \"../fs.ts\";\nimport type { WalkEntry } from \"@std/fs/walk\";\nimport type { FsRou"
  },
  {
    "path": "packages/fresh/src/dev/fs_crawl_test.ts",
    "chars": 1169,
    "preview": "import { expect } from \"@std/expect/expect\";\nimport { createFakeFs } from \"../test_utils.ts\";\nimport { walkDir } from \"."
  },
  {
    "path": "packages/fresh/src/dev/middlewares/automatic_workspace_folders.ts",
    "chars": 1876,
    "preview": "import { eTag, ifNoneMatch } from \"@std/http/etag\";\nimport { generate } from \"@std/uuid/v5\";\nimport { NAMESPACE_URL } fr"
  },
  {
    "path": "packages/fresh/src/dev/middlewares/error_overlay/code_frame.ts",
    "chars": 3281,
    "preview": "import * as path from \"@std/path\";\n\nfunction tabs2Spaces(str: string) {\n  return str.replace(/^\\t+/, (tabs) => \"  \".repe"
  },
  {
    "path": "packages/fresh/src/dev/middlewares/error_overlay/middleware.tsx",
    "chars": 1062,
    "preview": "import { DEV_ERROR_OVERLAY_URL } from \"../../../constants.ts\";\nimport { HttpError } from \"../../../error.ts\";\nimport typ"
  },
  {
    "path": "packages/fresh/src/dev/middlewares/error_overlay/middleware_test.tsx",
    "chars": 2628,
    "preview": "import { expect } from \"@std/expect\";\nimport { App } from \"../../../app.ts\";\nimport { FakeServer } from \"../../../test_u"
  },
  {
    "path": "packages/fresh/src/dev/middlewares/error_overlay/overlay.tsx",
    "chars": 4044,
    "preview": "import type { ComponentChildren } from \"preact\";\n\n// Just to get some syntax highlighting\nconst css = (arr: TemplateStri"
  },
  {
    "path": "packages/fresh/src/dev/middlewares/live_reload.ts",
    "chars": 1075,
    "preview": "import type { Middleware } from \"../../middlewares/mod.ts\";\nimport { ALIVE_URL } from \"../../constants.ts\";\n\n// Live rel"
  },
  {
    "path": "packages/fresh/src/dev/mod.ts",
    "chars": 204,
    "preview": "export {\n  Builder,\n  type BuildOptions,\n  type ResolvedBuildConfig,\n} from \"./builder.ts\";\nexport {\n  type OnTransformA"
  },
  {
    "path": "packages/fresh/src/dev/update_check.ts",
    "chars": 4015,
    "preview": "import * as semver from \"@std/semver\";\nimport * as colors from \"@std/fmt/colors\";\nimport * as path from \"@std/path\";\nimp"
  },
  {
    "path": "packages/fresh/src/dev/update_check_test.ts",
    "chars": 9844,
    "preview": "import * as path from \"@std/path\";\nimport denoJson from \"../../deno.json\" with { type: \"json\" };\nimport { getStdOutput }"
  },
  {
    "path": "packages/fresh/src/error.ts",
    "chars": 2013,
    "preview": "import { type ErrorStatus, STATUS_TEXT } from \"@std/http/status\";\n\nexport type { ErrorStatus };\n\n/**\n * Error that's thr"
  },
  {
    "path": "packages/fresh/src/error_test.ts",
    "chars": 449,
    "preview": "import { expect } from \"@std/expect\";\nimport { HttpError } from \"./error.ts\";\n\nDeno.test(\"HttpError\", () => {\n  const er"
  },
  {
    "path": "packages/fresh/src/file_url.ts",
    "chars": 543,
    "preview": "import * as pathPosix from \"@std/path/posix\";\nimport * as path from \"@std/path\";\n\nexport type FileUrl = string & { reado"
  },
  {
    "path": "packages/fresh/src/file_url_test.ts",
    "chars": 449,
    "preview": "import { expect } from \"@std/expect\";\nimport { pathToFileUrl, relativeUrl } from \"./file_url.ts\";\n\nDeno.test(\"pathToFile"
  },
  {
    "path": "packages/fresh/src/fs.ts",
    "chars": 969,
    "preview": "import { walk, type WalkEntry, type WalkOptions } from \"@std/fs/walk\";\n\nexport interface FsAdapter {\n  cwd(): string;\n  "
  },
  {
    "path": "packages/fresh/src/fs_routes.ts",
    "chars": 9973,
    "preview": "import type { AnyComponent } from \"preact\";\nimport type { MaybeLazy, Route, RouteConfig } from \"./types.ts\";\nimport type"
  },
  {
    "path": "packages/fresh/src/fs_routes_test.tsx",
    "chars": 43290,
    "preview": "import { App, setBuildCache } from \"./app.ts\";\nimport { type FreshFsMod, sortRoutePaths } from \"./fs_routes.ts\";\nimport "
  },
  {
    "path": "packages/fresh/src/handlers.ts",
    "chars": 6769,
    "preview": "import type { Context } from \"./context.ts\";\nimport type { Method } from \"./router.ts\";\n\nexport interface PageResponse<T"
  },
  {
    "path": "packages/fresh/src/internals.ts",
    "chars": 238,
    "preview": "import * as path from \"@std/path\";\n\nexport { setBuildCache, setErrorInterceptor } from \"./app.ts\";\nexport { IslandPrepar"
  },
  {
    "path": "packages/fresh/src/internals_dev.ts",
    "chars": 535,
    "preview": "export { crawlFsItem } from \"./dev/fs_crawl.ts\";\nexport { type FsAdapter, fsAdapter } from \"./fs.ts\";\nexport {\n  type Fs"
  },
  {
    "path": "packages/fresh/src/jsonify/__snapshots__/round_trip_test.ts.snap",
    "chars": 2068,
    "preview": "export const snapshot = {};\n\nsnapshot[`round trip - undefined 1`] = `\"-1\"`;\n\nsnapshot[`round trip - null 1`] = `\"-2\"`;\n\n"
  },
  {
    "path": "packages/fresh/src/jsonify/constants.ts",
    "chars": 192,
    "preview": "export const UNDEFINED = -1;\nexport const NULL = -2;\nexport const NAN = -3;\nexport const INFINITY_POS = -4;\nexport const"
  },
  {
    "path": "packages/fresh/src/jsonify/custom_test.ts",
    "chars": 2434,
    "preview": "import { expect } from \"@std/expect\";\nimport { parse } from \"./parse.ts\";\nimport { stringify } from \"./stringify.ts\";\nim"
  },
  {
    "path": "packages/fresh/src/jsonify/parse.ts",
    "chars": 3666,
    "preview": "import {\n  HOLE,\n  INFINITY_NEG,\n  INFINITY_POS,\n  NAN,\n  NULL,\n  UNDEFINED,\n  ZERO_NEG,\n} from \"./constants.ts\";\n\n// de"
  },
  {
    "path": "packages/fresh/src/jsonify/round_trip_test.ts",
    "chars": 1033,
    "preview": "import { expect } from \"@std/expect\";\nimport { parse } from \"./parse.ts\";\nimport { assertSnapshot } from \"@std/testing/s"
  },
  {
    "path": "packages/fresh/src/jsonify/stringify.ts",
    "chars": 5389,
    "preview": "import {\n  HOLE,\n  INFINITY_NEG,\n  INFINITY_POS,\n  NAN,\n  NULL,\n  UNDEFINED,\n  ZERO_NEG,\n} from \"./constants.ts\";\n\nexpor"
  },
  {
    "path": "packages/fresh/src/jsonify/stringify_test.ts",
    "chars": 369,
    "preview": "import { expect } from \"@std/expect\";\nimport { stringify } from \"./stringify.ts\";\n\nDeno.test(\"stringify - object prototy"
  },
  {
    "path": "packages/fresh/src/middlewares/cors.ts",
    "chars": 5721,
    "preview": "import type { Context } from \"../context.ts\";\nimport type { Middleware } from \"./mod.ts\";\n\nexport type CORSOptions<State"
  },
  {
    "path": "packages/fresh/src/middlewares/cors_test.ts",
    "chars": 6538,
    "preview": "import { App } from \"../app.ts\";\nimport { cors } from \"./cors.ts\";\nimport { expect } from \"@std/expect\";\n\nDeno.test(\"COR"
  },
  {
    "path": "packages/fresh/src/middlewares/csp.ts",
    "chars": 1962,
    "preview": "import type { Middleware } from \"./mod.ts\";\n\n/** Options for Content-Security-Policy middleware */\nexport interface CSPO"
  },
  {
    "path": "packages/fresh/src/middlewares/csp_test.ts",
    "chars": 2381,
    "preview": "import { expect } from \"@std/expect/expect\";\nimport { App } from \"../app.ts\";\nimport { csp } from \"./csp.ts\";\n\nDeno.test"
  },
  {
    "path": "packages/fresh/src/middlewares/csrf.ts",
    "chars": 2676,
    "preview": "import type { Context } from \"../context.ts\";\nimport { HttpError } from \"../error.ts\";\nimport type { Middleware } from \""
  },
  {
    "path": "packages/fresh/src/middlewares/csrf_test.ts",
    "chars": 3282,
    "preview": "import { App } from \"../app.ts\";\nimport type { Method } from \"../router.ts\";\nimport { csrf, type CsrfOptions } from \"./c"
  },
  {
    "path": "packages/fresh/src/middlewares/mod.ts",
    "chars": 4626,
    "preview": "import { type Context, getInternals } from \"../context.ts\";\nimport type { App as _App } from \"../app.ts\";\nimport type { "
  },
  {
    "path": "packages/fresh/src/middlewares/mod_test.ts",
    "chars": 4152,
    "preview": "import { runMiddlewares } from \"./mod.ts\";\nimport { expect } from \"@std/expect\";\nimport { serveMiddleware } from \"../tes"
  },
  {
    "path": "packages/fresh/src/middlewares/static_files.ts",
    "chars": 3734,
    "preview": "import type { Middleware } from \"./mod.ts\";\nimport { ASSET_CACHE_BUST_KEY } from \"../constants.ts\";\nimport { BUILD_ID } "
  },
  {
    "path": "packages/fresh/src/middlewares/static_files_test.ts",
    "chars": 7388,
    "preview": "import { staticFiles } from \"./static_files.ts\";\nimport { serveMiddleware } from \"../test_utils.ts\";\nimport type { Build"
  },
  {
    "path": "packages/fresh/src/middlewares/trailing_slashes.ts",
    "chars": 850,
    "preview": "import type { Middleware } from \"./mod.ts\";\n\n/**\n * Fresh middleware to force URLs to end with a slash or never end with"
  },
  {
    "path": "packages/fresh/src/middlewares/trailing_slashes_test.ts",
    "chars": 1665,
    "preview": "// deno-lint-ignore-file require-await\nimport { trailingSlashes } from \"./trailing_slashes.ts\";\nimport { expect } from \""
  },
  {
    "path": "packages/fresh/src/mod.ts",
    "chars": 984,
    "preview": "export { App, type ListenOptions } from \"./app.ts\";\nexport { trailingSlashes } from \"./middlewares/trailing_slashes.ts\";"
  },
  {
    "path": "packages/fresh/src/otel.ts",
    "chars": 506,
    "preview": "import { type Span, SpanStatusCode, trace } from \"@opentelemetry/api\";\nimport denoJson from \"../deno.json\" with { type: "
  },
  {
    "path": "packages/fresh/src/render.ts",
    "chars": 2464,
    "preview": "import {\n  type AnyComponent,\n  type FunctionComponent,\n  h,\n  type RenderableProps,\n  type VNode,\n} from \"preact\";\nimpo"
  },
  {
    "path": "packages/fresh/src/router.ts",
    "chars": 7559,
    "preview": "export type Method =\n  | \"HEAD\"\n  | \"GET\"\n  | \"POST\"\n  | \"PATCH\"\n  | \"PUT\"\n  | \"DELETE\"\n  | \"OPTIONS\";\n\nexport type Rout"
  },
  {
    "path": "packages/fresh/src/router_test.ts",
    "chars": 5920,
    "preview": "import { expect } from \"@std/expect\";\nimport {\n  IS_PATTERN,\n  mergePath,\n  pathToPattern,\n  patternToSegments,\n  UrlPat"
  },
  {
    "path": "packages/fresh/src/runtime/client/dev.ts",
    "chars": 2864,
    "preview": "import \"preact/debug\";\nexport * from \"./mod.ts\";\nimport { IS_BROWSER } from \"../shared.ts\";\n\nlet ws: WebSocket;\nlet revi"
  },
  {
    "path": "packages/fresh/src/runtime/client/mod.ts",
    "chars": 207,
    "preview": "import \"./polyfills.ts\";\nimport \"./preact_hooks_client.ts\";\nimport \"./partials.ts\";\nexport { asset, IS_BROWSER, Partial,"
  },
  {
    "path": "packages/fresh/src/runtime/client/partials.ts",
    "chars": 15770,
    "preview": "import { type ComponentChildren, h } from \"preact\";\nimport {\n  CLIENT_NAV_ATTR,\n  DATA_ANCESTOR,\n  DATA_CURRENT,\n  match"
  },
  {
    "path": "packages/fresh/src/runtime/client/polyfills.ts",
    "chars": 231,
    "preview": "// deno-lint-ignore-file ban-unknown-rule-code ban-unused-ignore\n// Polyfill for old safari versions\nif (typeof globalTh"
  },
  {
    "path": "packages/fresh/src/runtime/client/preact_hooks_client.ts",
    "chars": 3279,
    "preview": "import { Fragment, h, options as preactOptions } from \"preact\";\nimport {\n  assetHashingHook,\n  CLIENT_NAV_ATTR,\n  type I"
  },
  {
    "path": "packages/fresh/src/runtime/client/reviver.ts",
    "chars": 16642,
    "preview": "import {\n  Component,\n  type ComponentChildren,\n  type ComponentType,\n  Fragment,\n  h,\n  render,\n  type VNode,\n} from \"p"
  },
  {
    "path": "packages/fresh/src/runtime/head.ts",
    "chars": 302,
    "preview": "import { type ComponentChildren, createContext, h } from \"preact\";\n\nexport const HeadContext = createContext(false);\n\nex"
  },
  {
    "path": "packages/fresh/src/runtime/server/preact_hooks.ts",
    "chars": 19433,
    "preview": "import {\n  type Component,\n  type ComponentChildren,\n  type ComponentType,\n  Fragment,\n  h,\n  isValidElement,\n  type Opt"
  },
  {
    "path": "packages/fresh/src/runtime/shared.ts",
    "chars": 1719,
    "preview": "import type { ComponentChildren, VNode } from \"preact\";\nimport { BUILD_ID } from \"@fresh/build-id\";\nimport { assetIntern"
  },
  {
    "path": "packages/fresh/src/runtime/shared_internal.ts",
    "chars": 4634,
    "preview": "import type { Component, Options as PreactOptions, VNode } from \"preact\";\nimport { ASSET_CACHE_BUST_KEY } from \"../const"
  },
  {
    "path": "packages/fresh/src/segments.ts",
    "chars": 5857,
    "preview": "import type { AnyComponent } from \"preact\";\nimport type { MaybeLazyMiddleware, Middleware } from \"./middlewares/mod.ts\";"
  },
  {
    "path": "packages/fresh/src/segments_test.ts",
    "chars": 1196,
    "preview": "import { expect } from \"@std/expect\";\nimport { getOrCreateSegment, newSegment } from \"./segments.ts\";\n\nDeno.test(\"findOr"
  },
  {
    "path": "packages/fresh/src/server/tailwind_aot_error_page.tsx",
    "chars": 1121,
    "preview": "const LINK = \"https://fresh.deno.dev/docs/concepts/ahead-of-time-builds\";\n\nexport default function TailwindErrorPage() {"
  },
  {
    "path": "packages/fresh/src/test_utils.ts",
    "chars": 5879,
    "preview": "import { Context, type ServerIslandRegistry } from \"./context.ts\";\nimport type { FsAdapter } from \"./fs.ts\";\nimport type"
  },
  {
    "path": "packages/fresh/src/types.ts",
    "chars": 2308,
    "preview": "import type { RouteHandler } from \"./handlers.ts\";\nimport type { Method } from \"./router.ts\";\nimport type { RouteCompone"
  }
]

// ... and 285 more files (download for full content)

About this extraction

This page contains the full source code of the denoland/fresh GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 485 files (1.3 MB), approximately 367.9k tokens, and a symbol index with 849 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!