├── .gitattributes ├── .github ├── CONTRIBUTING.md ├── dependabot.yml └── workflows │ ├── ci.yml │ ├── deploy.yml │ ├── post_publish.yml │ └── publish.yml ├── .gitignore ├── .vscode ├── extensions.json ├── settings.json └── tailwind.json ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── _typos.toml ├── deno.json ├── deno.lock ├── docs ├── canary │ ├── examples │ │ └── migration-guide.md │ └── the-canary-version │ │ └── index.md ├── latest │ ├── 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 └── toc.ts ├── examples ├── LICENSE ├── README.md ├── deno.json └── src │ ├── app1.tsx │ ├── app2.tsx │ ├── island.tsx │ └── shared.tsx ├── init ├── README.md ├── deno.json └── src │ ├── assets │ └── favicon.ico │ ├── init.ts │ ├── init_test.ts │ └── mod.ts ├── plugin-tailwindcss ├── README.md ├── deno.json └── src │ ├── compiler.ts │ ├── mod.ts │ └── types.ts ├── src ├── app.ts ├── app_test.tsx ├── build_cache.ts ├── build_cache_test.ts ├── compat.ts ├── config.ts ├── config_test.ts ├── constants.ts ├── context.ts ├── context_test.tsx ├── define.ts ├── define_test.ts ├── dev │ ├── builder.ts │ ├── builder_test.ts │ ├── dev_build_cache.ts │ ├── dev_build_cache_test.ts │ ├── esbuild.ts │ ├── file_transformer.ts │ ├── file_transformer_test.ts │ ├── middlewares │ │ ├── automatic_workspace_folders.ts │ │ ├── error_overlay │ │ │ ├── code_frame.tsx │ │ │ ├── middleware.tsx │ │ │ ├── middleware_test.tsx │ │ │ └── overlay.tsx │ │ └── live_reload.ts │ ├── mod.ts │ ├── update_check.ts │ └── update_check_test.ts ├── error.ts ├── error_test.ts ├── finish_setup.tsx ├── fs.ts ├── handlers.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 │ ├── mod.ts │ ├── mod_test.ts │ ├── static_files.ts │ ├── static_files_test.ts │ ├── trailing_slashes.ts │ └── trailing_slashes_test.ts ├── mod.ts ├── otel.ts ├── plugins │ └── fs_routes │ │ ├── mod.ts │ │ ├── mod_test.tsx │ │ ├── render_middleware.ts │ │ └── render_middleware_test.tsx ├── router.ts ├── router_test.ts ├── runtime │ ├── build_id.ts │ ├── client │ │ ├── dev.ts │ │ ├── mod.tsx │ │ ├── partials.ts │ │ ├── polyfills.ts │ │ ├── preact_hooks_client.ts │ │ └── reviver.ts │ ├── server │ │ └── preact_hooks.tsx │ ├── shared.ts │ └── shared_internal.tsx ├── server │ └── tailwind_aot_error_page.tsx ├── test_utils.ts ├── types.ts ├── utils.ts └── utils_test.ts ├── tests ├── active_links_test.tsx ├── fixture_island_groups │ └── routes │ │ ├── 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 │ ├── Counter.tsx │ ├── CounterWithSlots.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 ├── islands_test.tsx ├── lorem_ipsum.txt ├── partials_test.tsx ├── precompile_test.ts └── test_utils.tsx ├── tools ├── check_docs.ts └── release.ts ├── update ├── README.md ├── deno.json └── src │ ├── mod.ts │ ├── update.ts │ ├── update_test.ts │ └── utils.ts ├── versions.json └── www ├── README.md ├── components ├── CodeBlock.tsx ├── CodeWindow.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 ├── CopyArea.tsx ├── 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 ├── docs │ ├── deno-deploy-gh-action.jpg │ └── fresh-partial-docs.png ├── docsearch.css ├── favicon.ico ├── fonts │ ├── FixelVariable.woff2 │ └── FixelVariableItalic.woff2 ├── fresh-arrow.svg ├── fresh-badge-dark.svg ├── fresh-badge.svg ├── gallery │ ├── banner-chart.png │ ├── banner-tabler-icons.png │ ├── grid.svg │ └── hero-bg.webp ├── google40caa9e535ae39e9.html ├── icons.svg ├── illustration │ ├── deno-plush.svg │ └── lemon-squash.svg ├── lemon.svg ├── logo.svg ├── logos │ ├── deno.svg │ ├── preact.svg │ └── typescript.svg ├── markdown.css ├── og-image.webp ├── prism.css ├── showcase │ ├── Denosoar1x.jpg │ ├── Denosoar2x.jpg │ ├── MergePanic1x.jpg │ ├── MergePanic2x.jpg │ ├── Paquet1x.jpg │ ├── Paquet2x.jpg │ ├── adam-portfolio1x.jpg │ ├── adam-portfolio2x.jpg │ ├── ajvanegasv1x.jpg │ ├── ajvanegasv2x.jpg │ ├── andbounds1x.jpg │ ├── andbounds2x.jpg │ ├── aquavibes1x.jpg │ ├── aquavibes2x.jpg │ ├── awesome-fresh1x.jpg │ ├── awesome-fresh2x.jpg │ ├── balello1x.jpg │ ├── balello2x.jpg │ ├── battleship1x.jpg │ ├── battleship2x.jpg │ ├── cgpa-au-20211x.jpg │ ├── cgpa-au-20212x.jpg │ ├── cs2items1x.jpg │ ├── cs2items2x.jpg │ ├── d3nodata1x.jpg │ ├── d3nodata2x.jpg │ ├── deco.webp │ ├── deno-artwork1x.jpg │ ├── deno-artwork2x.jpg │ ├── deno-diary1x.jpg │ ├── deno-diary2x.jpg │ ├── deno-jobs1x.jpg │ ├── deno-jobs2x.jpg │ ├── deno-saaskit1x.jpg │ ├── deno-saaskit2x.jpg │ ├── deno1x.jpg │ ├── deno2x.jpg │ ├── denopaste1x.jpg │ ├── denopaste2x.jpg │ ├── dgaubert1x.jpg │ ├── dgaubert2x.jpg │ ├── diKnow1x.jpg │ ├── diKnow2x.jpg │ ├── echo-echo1x.jpg │ ├── echo-echo2x.jpg │ ├── evilmonkey19-cv1x.jpg │ ├── evilmonkey19-cv2x.jpg │ ├── festwithme1x.jpg │ ├── festwithme2x.jpg │ ├── filter-hn1x.jpg │ ├── filter-hn2x.jpg │ ├── fondest1x.jpg │ ├── fondest2x.jpg │ ├── fresh-blog-system1x.jpg │ ├── fresh-blog-system2x.jpg │ ├── fresh-notion-blog1x.jpg │ ├── fresh-notion-blog2x.jpg │ ├── fresh-project-manager1x.jpg │ ├── fresh-project-manager2x.jpg │ ├── fresh-strapi1x.jpg │ ├── fresh-strapi2x.jpg │ ├── fresh-todo1x.jpg │ ├── fresh-todo2x.jpg │ ├── fresh1x.jpg │ ├── fresh2x.jpg │ ├── grape-chat1x.jpg │ ├── grape-chat2x.jpg │ ├── guigui641x.jpg │ ├── guigui642x.jpg │ ├── hazn1x.jpg │ ├── hazn2x.jpg │ ├── hicoffee1x.jpg │ ├── hicoffee2x.jpg │ ├── hn1x.jpg │ ├── hn2x.jpg │ ├── imasparql-dd1x.jpg │ ├── imasparql-dd2x.jpg │ ├── javaminidoodle1x.jpg │ ├── javaminidoodle2x.jpg │ ├── jptchat1x.jpg │ ├── jptchat2x.jpg │ ├── jsr1x.jpg │ ├── jsr2x.jpg │ ├── kadode_portal1x.jpg │ ├── kadode_portal2x.jpg │ ├── kanji-academy1x.jpg │ ├── kanji-academy2x.jpg │ ├── kita1x.jpg │ ├── kita2x.jpg │ ├── ldkit1x.jpg │ ├── ldkit2x.jpg │ ├── learn-mandarin1x.jpg │ ├── learn-mandarin2x.jpg │ ├── liberchat1x.jpg │ ├── liberchat2x.jpg │ ├── link-maker1x.jpg │ ├── link-maker2x.jpg │ ├── linksapp1x.jpg │ ├── linksapp2x.jpg │ ├── living-pixel1x.jpg │ ├── living-pixel2x.jpg │ ├── localseostudio1x.jpg │ ├── localseostudio2x.jpg │ ├── m33t1x.jpg │ ├── m33t2x.jpg │ ├── melon1x.jpg │ ├── melon2x.jpg │ ├── merch1x.jpg │ ├── merch2x.jpg │ ├── mieszko1x.jpg │ ├── mieszko2x.jpg │ ├── miguel-rangel-site1x.jpg │ ├── miguel-rangel-site2x.jpg │ ├── moe-counter1x.jpg │ ├── moe-counter2x.jpg │ ├── mooxl1x.jpg │ ├── mooxl2x.jpg │ ├── openai-semantic-search1x.jpg │ ├── openai-semantic-search2x.jpg │ ├── optimem1x.jpg │ ├── optimem2x.jpg │ ├── pile-up1x.jpg │ ├── pile-up2x.jpg │ ├── pollify1x.jpg │ ├── pollify2x.jpg │ ├── ppaste1x.jpg │ ├── ppaste2x.jpg │ ├── rebstorm1x.jpg │ ├── rebstorm2x.jpg │ ├── rfui1x.jpg │ ├── rfui2x.jpg │ ├── teams-template1x.jpg │ ├── teams-template2x.jpg │ ├── text2audio1x.jpg │ ├── text2audio2x.jpg │ ├── thoth-doc1x.jpg │ ├── thoth-doc2x.jpg │ ├── ticoxs1x.jpg │ ├── ticoxs2x.jpg │ ├── uspb1x.jpg │ ├── uspb2x.jpg │ ├── videopoker-academy1x.jpg │ ├── videopoker-academy2x.jpg │ ├── virtualfreight1x.jpg │ ├── virtualfreight2x.jpg │ ├── webhook-manager1x.jpg │ ├── webhook-manager2x.jpg │ ├── wricord1x.jpg │ ├── wricord2x.jpg │ ├── wtfcongress1x.jpg │ ├── wtfcongress2x.jpg │ ├── yaml-to-ts1x.jpg │ ├── yaml-to-ts2x.jpg │ ├── ycrm1x.jpg │ ├── ycrm2x.jpg │ ├── zhiblog1x.jpg │ └── zhiblog2x.jpg ├── styles.css └── wordmark.svg ├── tailwind.config.ts ├── telemetry.ts └── utils ├── markdown.ts ├── screenshot.ts └── state.ts /.gitattributes: -------------------------------------------------------------------------------- 1 | # Use Unix line endings in all text files. 2 | * text=auto eol=lf -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | ## Submitting a pull request 4 | 5 | First, please be sure to 6 | [install Puppeteer](https://github.com/lucacasonato/deno-puppeteer#installation). 7 | Then, please ensure `deno task ok` is run and successfully passes. 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | # Check for updates to GitHub Actions every week 7 | interval: "weekly" 8 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | test: 11 | runs-on: ${{ matrix.os }} 12 | timeout-minutes: 10 13 | 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | deno: ["v2.x", "canary"] 18 | os: [macOS-latest, windows-latest, ubuntu-latest] 19 | include: 20 | - os: ubuntu-latest 21 | cache_path: ~/.cache/deno/ 22 | - os: macos-latest 23 | cache_path: ~/Library/Caches/deno/ 24 | - os: windows-latest 25 | cache_path: ~\AppData\Local\deno\ 26 | 27 | steps: 28 | - name: Checkout repo 29 | uses: actions/checkout@v4 30 | 31 | - name: Setup Deno 32 | uses: denoland/setup-deno@v2 33 | with: 34 | cache: true 35 | deno-version: ${{ matrix.deno }} 36 | 37 | - name: Verify formatting 38 | if: startsWith(matrix.os, 'ubuntu') && matrix.deno == 'v2.x' 39 | run: deno fmt --check 40 | 41 | - name: Run linter 42 | if: startsWith(matrix.os, 'ubuntu') && matrix.deno == 'v2.x' 43 | run: deno lint 44 | 45 | - name: Spell-check 46 | if: startsWith(matrix.os, 'ubuntu') && matrix.deno == 'v2.x' 47 | uses: crate-ci/typos@master 48 | 49 | - name: Type check project 50 | run: deno task check:types 51 | 52 | - name: Run tests 53 | run: deno task test 54 | 55 | - name: Check docs 56 | run: deno task check:docs 57 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | on: 3 | push: 4 | branches: [main] 5 | pull_request: 6 | branches: [main] 7 | 8 | jobs: 9 | deploy: 10 | name: Deploy 11 | runs-on: ubuntu-latest 12 | 13 | permissions: 14 | id-token: write # Needed for auth with Deno Deploy 15 | contents: read # Needed to clone the repository 16 | 17 | steps: 18 | - name: Clone repository 19 | uses: actions/checkout@v4 20 | 21 | - name: Install Deno 22 | uses: denoland/setup-deno@v2 23 | with: 24 | cache: true 25 | deno-version: rc 26 | 27 | - name: Build step 28 | working-directory: ./www 29 | run: "deno task build" 30 | 31 | - name: Upload to Deno Deploy 32 | uses: denoland/deployctl@v1 33 | with: 34 | project: "fresh" 35 | entrypoint: "./www/main.ts" 36 | root: "." 37 | -------------------------------------------------------------------------------- /.github/workflows/post_publish.yml: -------------------------------------------------------------------------------- 1 | name: post_publish 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | update-dl-version: 9 | name: update dl.deno.land version 10 | runs-on: ubuntu-22.04 11 | if: github.repository == 'denoland/fresh' 12 | steps: 13 | - name: Checkout repo 14 | uses: actions/checkout@v4 15 | 16 | - name: Authenticate with Google Cloud 17 | uses: google-github-actions/auth@v2 18 | with: 19 | project_id: denoland 20 | credentials_json: ${{ secrets.GCP_SA_KEY }} 21 | export_environment_variables: true 22 | create_credentials_file: true 23 | 24 | - name: Setup gcloud 25 | uses: google-github-actions/setup-gcloud@v2 26 | with: 27 | project_id: denoland 28 | 29 | - name: Upload version file to dl.deno.land 30 | run: | 31 | cat versions.json | jq -r ".[0]" > release-latest.txt 32 | gsutil -h "Cache-Control: no-cache" cp release-latest.txt gs://dl.deno.land/fresh/release-latest.txt 33 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish JSR 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | publish: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: read 13 | id-token: write 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: Install Deno 19 | uses: denoland/setup-deno@v2 20 | with: 21 | cache: true 22 | 23 | - name: Publish Fresh 24 | run: deno publish 25 | 26 | - name: Publish @fresh/init 27 | working-directory: ./init 28 | run: deno publish 29 | 30 | - name: Publish @fresh/plugin-tailwindcss 31 | working-directory: ./plugin-tailwindcss 32 | run: deno publish 33 | 34 | - name: Publish @fresh/update 35 | working-directory: ./update 36 | run: deno publish 37 | 38 | - name: Publish @fresh/examples 39 | working-directory: ./examples 40 | run: deno publish 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _fresh/ 2 | vendor/ 3 | node_modules/ 4 | .docs/ 5 | .DS_Store 6 | tmp_* 7 | coverage/ -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "denoland.vscode-deno" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.enable": true, 3 | "deno.lint": true, 4 | "deno.codeLens.test": true, 5 | "deno.documentPreloadLimit": 2000, 6 | "editor.formatOnSave": true, 7 | "editor.defaultFormatter": "denoland.vscode-deno", 8 | "[typescriptreact]": { 9 | "editor.defaultFormatter": "denoland.vscode-deno" 10 | }, 11 | "[typescript]": { 12 | "editor.defaultFormatter": "denoland.vscode-deno" 13 | }, 14 | "[javascriptreact]": { 15 | "editor.defaultFormatter": "denoland.vscode-deno" 16 | }, 17 | "[javascript]": { 18 | "editor.defaultFormatter": "denoland.vscode-deno" 19 | }, 20 | "[markdown]": { 21 | "editor.defaultFormatter": "denoland.vscode-deno" 22 | }, 23 | "css.customData": [ 24 | ".vscode/tailwind.json" 25 | ], 26 | "[json]": { 27 | "editor.defaultFormatter": "denoland.vscode-deno" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.vscode/tailwind.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1.1, 3 | "atDirectives": [ 4 | { 5 | "name": "@tailwind", 6 | "description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.", 7 | "references": [ 8 | { 9 | "name": "Tailwind Documentation", 10 | "url": "https://tailwindcss.com/docs/functions-and-directives#tailwind" 11 | } 12 | ] 13 | }, 14 | { 15 | "name": "@apply", 16 | "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.", 17 | "references": [ 18 | { 19 | "name": "Tailwind Documentation", 20 | "url": "https://tailwindcss.com/docs/functions-and-directives#apply" 21 | } 22 | ] 23 | }, 24 | { 25 | "name": "@responsive", 26 | "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", 27 | "references": [ 28 | { 29 | "name": "Tailwind Documentation", 30 | "url": "https://tailwindcss.com/docs/functions-and-directives#responsive" 31 | } 32 | ] 33 | }, 34 | { 35 | "name": "@screen", 36 | "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", 37 | "references": [ 38 | { 39 | "name": "Tailwind Documentation", 40 | "url": "https://tailwindcss.com/docs/functions-and-directives#screen" 41 | } 42 | ] 43 | }, 44 | { 45 | "name": "@variants", 46 | "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", 47 | "references": [ 48 | { 49 | "name": "Tailwind Documentation", 50 | "url": "https://tailwindcss.com/docs/functions-and-directives#variants" 51 | } 52 | ] 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2023 Luca Casonato 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /_typos.toml: -------------------------------------------------------------------------------- 1 | [files] 2 | extend-exclude = [ 3 | "tests/fixture_partials/routes/scroll_restoration/index.tsx", 4 | "www/static/fonts/FixelVariable.woff2", 5 | "www/static/fonts/FixelVariableItalic.woff2", 6 | "tests/lorem_ipsum.txt", 7 | ] 8 | 9 | [default] 10 | extend-ignore-identifiers-re = ["Fixel"] 11 | -------------------------------------------------------------------------------- /docs/canary/the-canary-version/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Learn more about Fresh canary releases 4 | --- 5 | 6 | The canary version represents the current development state of Fresh. It's 7 | intended for testing work in progress features before it lands in a stable 8 | release. Whenever new code is merged into the `main` branch on 9 | [GitHub](https://github.com/denoland/fresh) a new canary version is created that 10 | matches the hash of the git commit. 11 | 12 | With the addition of new features that are not yet in a stable release, we need 13 | a place to update our documentation. That's what this section of the 14 | documentation is about. It contains all information about unreleased features 15 | and changes that will land in a stable release. 16 | -------------------------------------------------------------------------------- /docs/latest/concepts/architecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Fresh's architecture is designed to make it easy to build fast, scalable, and reliable applications. 4 | --- 5 | 6 | Fresh is designed to make it easy to build fast, scalable, and reliable 7 | applications. To do this, it makes opinionated decisions about how one should 8 | build web applications. These decisions are backed by strong empirical data 9 | gathered from experts in the field. Some examples of these principles are: 10 | 11 | - Page load times should be reduced to a minimum. 12 | - The work performed on the client should be minimized. 13 | - Errors should have a small blast radius - stuff should gracefully degrade. 14 | 15 | The single biggest architecture decision that Fresh makes is its usage of the 16 | [islands architecture][islands] pattern. This means that Fresh applications ship 17 | pure HTML to the client by default. Parts of a server-rendered page can then be 18 | independently re-hydrated with interactive widgets (islands). This means that 19 | the client is only responsible for rendering parts of the page that are 20 | interactive enough to warrant the extra effort. Any content that is purely 21 | static does not have related client-side JavaScript and is thus very 22 | lightweight. 23 | 24 | 25 | 26 | [islands]: https://www.patterns.dev/posts/islands-architecture/ 27 | -------------------------------------------------------------------------------- /docs/latest/concepts/data-fetching.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Data fetching in Fresh happens inside of route handler functions. These can pass route data to the page via page props. 4 | --- 5 | 6 | Server side data fetching in Fresh is accomplished through asynchronous handler 7 | functions. These handler functions can call a `ctx.render()` function with the 8 | data to be rendered as an argument. This data can then be retrieved by the page 9 | component through the `data` property on the `props`. 10 | 11 | Here is an example: 12 | 13 | ```tsx routes/projects/[id].tsx 14 | interface Project { 15 | name: string; 16 | stars: number; 17 | } 18 | 19 | export const handler: Handlers = { 20 | async GET(_req, ctx) { 21 | const project = await db.projects.findOne({ id: ctx.params.id }); 22 | if (!project) { 23 | return ctx.renderNotFound({ 24 | message: "Project does not exist", 25 | }); 26 | } 27 | return ctx.render(project); 28 | }, 29 | }; 30 | 31 | export default function ProjectPage(props: PageProps) { 32 | return ( 33 |
34 |

{props.data.name}

35 |

{props.data.stars} stars

36 |
37 | ); 38 | } 39 | ``` 40 | 41 | The type parameter on the `PageProps`, `Handlers`, `Handler`, and `FreshContext` 42 | can be used to enforce a TypeScript type to use for the render data. Fresh 43 | enforces during type checking that the types in all of these fields are 44 | compatible within a single page. 45 | 46 | ## Asynchronous routes 47 | 48 | As a shortcut for combining a `GET` handler with a route, you can define your 49 | route as `async`. An `async` route (a route that returns a promise) will be 50 | called with the `Request` and a `RouteContext` (similar to a `HandlerContext`). 51 | Here is the above example rewritten using this shortcut: 52 | 53 | ```tsx routes/projects/[id].tsx 54 | interface Project { 55 | name: string; 56 | stars: number; 57 | } 58 | 59 | export default async function ProjectPage(_req, ctx: FreshContext) { 60 | const project: Project | null = await db.projects.findOne({ 61 | id: ctx.params.id, 62 | }); 63 | 64 | if (!project) { 65 | return

Project not found

; 66 | } 67 | 68 | return ( 69 |
70 |

{project.name}

71 |

{project.stars} stars

72 |
73 | ); 74 | } 75 | ``` 76 | -------------------------------------------------------------------------------- /docs/latest/concepts/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | This chapter goes over some fundamental concepts of Fresh. 4 | --- 5 | 6 | This chapter goes over some fundamental concepts of Fresh. It covers the 7 | overarching architecture design of Fresh applications, as well as reference 8 | documentation about the various features of Fresh. 9 | -------------------------------------------------------------------------------- /docs/latest/concepts/server-components.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Fresh's architecture is designed to leverage server components by default. 4 | --- 5 | 6 | If you've read about Fresh's [architecture](/docs/concepts/architecture) then 7 | you know that it's based on the islands architecture pattern. The flip side of 8 | this is that everything else is, by default, a server component. When you 9 | [create a route](/docs/getting-started/create-a-route), all of the components 10 | used are rendered on the server. No JavaScript is sent to the client, unless you 11 | specifically include something from the `/islands/` folder. 12 | 13 | Internally, Fresh's rendering heavily leverages 14 | [preact-render-to-string](https://github.com/preactjs/preact-render-to-string). 15 | This is the exact library mentioned on Preact's 16 | [Server-Side Rendering](https://preactjs.com/guide/v10/server-side-rendering/) 17 | article. 18 | -------------------------------------------------------------------------------- /docs/latest/concepts/static-files.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Fresh has built-in support for serving static files. This is useful for serving images, CSS, and other static assets. 4 | --- 5 | 6 | Fresh automatically serves static assets placed in a `static/` directory in the 7 | project root. These assets are served at the root of the webserver, with a 8 | higher priority than routes. This means that if a given request matches a file 9 | in the `static/` folder, it is always served, even if there is a route that 10 | would also match the request. 11 | 12 | Static asset responses automatically get a `content-type` header assigned based 13 | on the file extension of the file on disk. Assets are also automatically 14 | streamed from disk to the client to improve performance and efficiency for both 15 | user and server. 16 | 17 | Fresh also adds an `etag` header to assets automatically and handles the 18 | `If-None-Match` header for incoming requests. 19 | 20 | ### Caching 21 | 22 | By default, no caching headers are added to assets. This can be disadvantageous 23 | in many scenarios, so Fresh makes it easy to serve assets with long cache 24 | lifetimes too. 25 | 26 | The first approach to do this is manual. The client runtime exports an `asset` 27 | function that takes an absolute path to the static asset and returns a "locked" 28 | version of this path that contains a build ID for cache busting. When the asset 29 | is requested at this "locked" path, it will be served with a cache lifetime of 30 | one year. 31 | 32 | ```jsx routes/page.tsx 33 | import { asset } from "$fresh/runtime.ts"; 34 | 35 | export default function Page() { 36 | return ( 37 |

38 | View brochure 39 |

40 | ); 41 | } 42 | ``` 43 | 44 | Fresh also does this automatically for `src` and `srcset` attributes in `` 45 | and `` HTML tags. These will automatically use "locked" paths if Fresh 46 | deems it safe to do so. You can always opt out of this behaviour per tag, by 47 | adding the `data-fresh-disable-lock` attribute. 48 | 49 | ```jsx 50 | ; 51 | ``` 52 | -------------------------------------------------------------------------------- /docs/latest/examples/active-links.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Style active links with ease in Fresh 4 | --- 5 | 6 | Fresh automatically enhances the accessibility of `` elements by adding the 7 | aria-current attribute when rendering links that match the current URL. This 8 | attribute is recognized by assistive technologies and clearly indicates the 9 | current page within a set of pages. 10 | 11 | - aria-current="page" - Added to links with an exact path match, enhancing 12 | accessibility by indicating the current page to assistive technologies. 13 | 14 | As we aim to improve accessibility, we encourage the use of aria-current for 15 | styling current links where applicable. 16 | 17 | ## Styling with CSS 18 | 19 | The aria-current attribute is easily styled with CSS using attribute selectors, 20 | providing a native way to visually differentiate the active link. 21 | 22 | ```css 23 | /* Give links pointing to the current page a green color */ 24 | a[aria-current="page"] { 25 | color: green; 26 | } 27 | 28 | /* Color all ancestor links of the current page */ 29 | a[aria-current="true"] { 30 | color: peachpuff; 31 | } 32 | ``` 33 | 34 | ## Tailwind / Twind 35 | 36 | In Tailwind or similar CSS frameworks like Twind, you can apply styles to 37 | elements with the aria-current attribute using bracket notation in your class 38 | definitions. However, the specific syntax varies slightly between Tailwind and 39 | Twind. For Tailwind, use the syntax: 40 | 41 | ```tsx 42 | function Menu() { 43 | return ( 44 | 45 | Link to some page 46 | 47 | ); 48 | } 49 | ``` 50 | 51 | For Twind, the syntax is: 52 | 53 | ```tsx 54 | function Menu() { 55 | return ( 56 | 57 | Link to some page 58 | 59 | ); 60 | } 61 | ``` 62 | 63 | ### Twind Plugin 64 | 65 | The original twind plugin (`import twindPlugin from "$fresh/plugins/twind.ts";`) 66 | supports the above style: 67 | 68 | ```tsx 69 | class="[aria-current='page']:text-green-600" 70 | ``` 71 | 72 | ### TwindV1 Plugin 73 | 74 | The new twind plugin (`import twindPlugin from "$fresh/plugins/twindv1.ts";`) 75 | requires a slightly different syntax (note the position of the left bracket): 76 | 77 | ```tsx 78 | class="aria-[current='page']:text-green-600" 79 | ``` 80 | -------------------------------------------------------------------------------- /docs/latest/examples/changing-the-src-dir.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Change the source directory to effectively manage your project. 4 | --- 5 | 6 | When you initialize a project with `deno run -A -r https://fresh.deno.dev`, 7 | you'll end up with a project like the following: 8 | 9 | ```txt Project Structure 10 | . 11 | ├── README.md 12 | ├── components 13 | │   └── Button.tsx 14 | ├── deno.json 15 | ├── dev.ts 16 | ├── fresh.gen.ts 17 | ├── islands 18 | │   └── Counter.tsx 19 | ├── main.ts 20 | ├── routes 21 | │   ├── greet 22 | │   │ ├── [name].tsx 23 | │   ├── api 24 | │   │   └── joke.ts 25 | │   ├── _404.tsx 26 | │   └── index.tsx 27 | └── static 28 | ├── favicon.ico 29 | └── logo.svg 30 | ``` 31 | 32 | ## Using a `src` directory 33 | 34 | If you'd like your code to live in an `src` directory (or any other directory of 35 | your choosing), then you'll need to do the following things: 36 | 37 | 1. Move all your files, except `deno.json` and `README.md`, to the `src` 38 | directory. 39 | 2. Modify the `start` task in `deno.json` to point to the new directory. 40 | 41 | Here's what the diff of `deno.json` looks like: 42 | 43 | ```diff deno.json 44 | { 45 | "lock": false, 46 | "tasks": { 47 | - "start": "deno run -A --watch=static/,routes/ dev.ts" 48 | + "start": "deno run -A --watch=src/static/,src/routes/ src/dev.ts" 49 | }, 50 | "imports": { 51 | "$fresh/": "file:///Users/reed/code/fresh/", 52 | ``` 53 | 54 | The resulting file structure looks like this: 55 | 56 | ```txt Project Structure 57 | . 58 | ├── README.md 59 | ├── deno.json 60 | └── src 61 | ├── components 62 | │   └── Button.tsx 63 | ├── dev.ts 64 | ├── fresh.gen.ts 65 | ├── islands 66 | │   └── Counter.tsx 67 | ├── main.ts 68 | ├── routes 69 | │   ├── greet 70 | │   │ ├── [name].tsx 71 | │   ├── api 72 | │   │   └── joke.ts 73 | │   ├── _404.tsx 74 | │   └── index.tsx 75 | └── static 76 | ├── favicon.ico 77 | └── logo.svg 78 | ``` 79 | 80 | Success! Your code now lives elsewhere. 81 | -------------------------------------------------------------------------------- /docs/latest/examples/handling-complex-routes.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Sometimes URL based routing isn't enough. 4 | --- 5 | 6 | The page on [routing](/docs/concepts/routing) hints at complex routing based on 7 | URL patterns using a `RouteConfig` object. Let's dive into this in a bit more 8 | detail. 9 | 10 | A `RouteConfig` has a `routeOverride` string property, which makes use of the 11 | [URL Pattern API](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API). 12 | Here you can define named groups, wildcards, regex groups, and other bits. 13 | 14 | ## Simple Route Config 15 | 16 | Let's look at the example from the routing page more closely. We'll flesh out 17 | the handler so that we end up with something like the following: 18 | 19 | ```ts routes/x.tsx 20 | import { FreshContext, RouteConfig } from "$fresh/server.ts"; 21 | 22 | export const handler = { 23 | GET(_req: Request, { params }: FreshContext) { 24 | console.log(params); 25 | return new Response(params.path); 26 | }, 27 | }; 28 | 29 | export const config: RouteConfig = { 30 | routeOverride: "/x/:module@:version/:path*", 31 | }; 32 | ``` 33 | 34 | Now if we hit the server with a request like 35 | `http://localhost:8000/x/bestModule@1.33.7/asdf`, then logging the params will 36 | show the following: 37 | 38 | ``` 39 | { 40 | module: "bestModule", 41 | version: "1.33.7", 42 | path: "asdf" 43 | } 44 | ``` 45 | 46 | ## Complex Route Config 47 | 48 | Let's look at something a bit more complex: 49 | 50 | ```ts routes/api.tsx 51 | import { FreshContext, RouteConfig } from "$fresh/server.ts"; 52 | 53 | export const handler = { 54 | GET(_req: Request, { params }: FreshContext) { 55 | console.log(params); 56 | return new Response(params.path); 57 | }, 58 | }; 59 | 60 | export const config: RouteConfig = { 61 | routeOverride: "/api/db/:resource(jobs?|bar)/:id(\\d+)?", 62 | }; 63 | ``` 64 | 65 | Values are available via `params.resource` and `params.id`. 66 | 67 | Here are some example URLs that match this: 68 | 69 | - /api/db/bar/1 70 | - /api/db/jobs/1 71 | - /api/db/job/1 72 | - /api/db/job 73 | - /api/db/jobs 74 | - /api/db/bar 75 | 76 | Here are some that don't: 77 | 78 | - /api/db/other/123 79 | - /api/db/jobs/abc 80 | - /api/db 81 | 82 | ## Regex 83 | 84 | At this point is should be clear that this is essentially an exercise in 85 | understanding regex. There are [numerous](https://regexr.com/) 86 | [resources](https://regex101.com/) [available](https://chat.openai.com/) for 87 | getting assistance with regex. 88 | -------------------------------------------------------------------------------- /docs/latest/examples/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | In this chapter of the Fresh documentation, you can find examples of features that you may like in your Fresh project. 4 | --- 5 | 6 | In this chapter of the Fresh documentation, you can find examples of features 7 | that you may like in your Fresh project. If there's a specific example you'd 8 | like to see here, please open 9 | [a GitHub discussion](https://github.com/denoland/fresh/discussions/new?category=ideas). 10 | 11 | - [Modifying the ``](./examples/modifying-the-head) 12 | - [Setting the language](./examples/setting-the-language) 13 | - [Writing tests](./examples/writing-tests) 14 | - [Changing the source directory](./examples/changing-the-src-dir) 15 | - [Initializing the server](./examples/init-the-server) 16 | - [Using Fresh canary version](./examples/using-fresh-canary-version) 17 | - [Dealing with CORS](./examples/dealing-with-cors) 18 | - [Creating a CRUD API](./examples/creating-a-crud-api) 19 | - [Handling complex routes](./examples/handling-complex-routes) 20 | - [Rendering markdown](./examples/rendering-markdown) 21 | - [Sharing state between islands](./examples/sharing-state-between-islands) 22 | - [Using CSP](./examples/using-csp) 23 | -------------------------------------------------------------------------------- /docs/latest/examples/rendering-raw-html.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | How to render raw HTML in Fresh. 4 | --- 5 | 6 | Text content in Fresh is always escaped, whether serverside rendered or rendered 7 | in islands. While this generally desired, it can create issues in certain 8 | situations. 9 | 10 | ## Warning 11 | 12 | The TL;DR is to use Preact's `dangerouslySetInnerHTML`. As the name implies, it 13 | should not be used lightly. 14 | 15 | Setting arbitrary HTML can be dangerous. Make sure you trust the source. 16 | Rendering user-supplied HTML to the DOM makes your site vulnerable to cross- 17 | site scripting. The markup must first be sanitizied, or better yet, something 18 | you trust. 19 | 20 | ## Example: Rendering JSON-LD 21 | 22 | Suppose we need to add some microdata markup to a page. The following will 23 | result in **escaped characters, and will not work**: 24 | 25 | ```tsx 26 | const json = ` 27 | { 28 | "@context": "http://schema.org", 29 | "@type": "PostalAddress", 30 | "streetAddress": "8888 University Drive", 31 | "addressLocality": "Burnaby", 32 | "addressRegion": "British Columbia" 33 | } 34 | `; 35 | 36 | export default function JsonLd() { 37 | return ; 38 | } 39 | ``` 40 | 41 | Instead, we can use `dangerouslySetInnerHTML`: 42 | 43 | ```tsx 44 | export default function JsonLd() { 45 | return ( 46 | 58 | 59 | 60 | 61 | 62 | 63 | ); 64 | }); 65 | -------------------------------------------------------------------------------- /www/routes/_error.tsx: -------------------------------------------------------------------------------- 1 | import { HttpError, type PageProps } from "fresh"; 2 | import LemonDrop from "../islands/LemonDrop.tsx"; 3 | 4 | export function ServerCodePage( 5 | props: { serverCode: number; codeDescription: string }, 6 | ) { 7 | return ( 8 | <> 9 |
10 |
11 | 12 |
13 |
14 |

15 | {props.serverCode} 16 |

17 | 18 |

19 | {props.codeDescription} 20 |

21 | 22 |

23 | Back to the Homepage 24 |

25 |
26 |
27 | 28 | ); 29 | } 30 | 31 | export default function PageNotFound(props: PageProps) { 32 | const error = props.error; 33 | if (error instanceof HttpError) { 34 | if (error.status === 404) { 35 | return ServerCodePage({ 36 | serverCode: 404, 37 | codeDescription: "Couldn’t find what you’re looking for.", 38 | }); 39 | } 40 | } 41 | 42 | return ServerCodePage({ 43 | serverCode: 500, 44 | codeDescription: "Oops! Something went wrong.", 45 | }); 46 | } 47 | -------------------------------------------------------------------------------- /www/routes/docs/_layout.tsx: -------------------------------------------------------------------------------- 1 | import type { PageProps } from "../../../src/context.ts"; 2 | 3 | export default function Layout({ Component }: PageProps) { 4 | return ( 5 |
6 |
7 | 8 |
9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /www/routes/docs/_middleware.ts: -------------------------------------------------------------------------------- 1 | import type { FreshContext } from "fresh"; 2 | 3 | const REDIRECTS: Record = { 4 | "/docs/getting-started/fetching-data": 5 | "/docs/getting-started/custom-handlers", 6 | }; 7 | 8 | export async function handler( 9 | ctx: FreshContext, 10 | ) { 11 | // Redirect from old doc URLs to new ones 12 | const redirect = REDIRECTS[ctx.url.pathname]; 13 | if (redirect) { 14 | const url = new URL(redirect, ctx.url.origin); 15 | return new Response("", { 16 | status: 307, 17 | headers: { location: url.href }, 18 | }); 19 | } 20 | 21 | return await ctx.next(); 22 | } 23 | -------------------------------------------------------------------------------- /www/routes/docs/index.tsx: -------------------------------------------------------------------------------- 1 | import { define } from "../../utils/state.ts"; 2 | 3 | export const handler = define.handlers({ 4 | GET(ctx) { 5 | return ctx.url.pathname === "/concepts/architechture" 6 | ? ctx.redirect("/docs/concepts/architecture") 7 | : ctx.redirect("/docs/introduction"); 8 | }, 9 | }); 10 | -------------------------------------------------------------------------------- /www/routes/raw.ts: -------------------------------------------------------------------------------- 1 | import type { RouteConfig } from "fresh"; 2 | import { format, parse } from "@std/semver"; 3 | import VERSIONS from "../../versions.json" with { type: "json" }; 4 | import { extname } from "@std/path"; 5 | import { define } from "../utils/state.ts"; 6 | 7 | const BASE_URL = "https://raw.githubusercontent.com/denoland/fresh/"; 8 | 9 | const contentTypes = new Map([ 10 | [".html", "text/plain"], 11 | [".ts", "application/typescript"], 12 | [".js", "application/javascript"], 13 | [".tsx", "text/tsx"], 14 | [".jsx", "text/jsx"], 15 | [".json", "application/json"], 16 | [".wasm", "application/wasm"], 17 | ]); 18 | 19 | export const handler = define.handlers({ 20 | async GET(ctx) { 21 | const accept = ctx.req.headers.get("Accept"); 22 | const isHTML = accept?.includes("text/html"); 23 | const { version, path } = ctx.params; 24 | 25 | const semver = parse(version); 26 | if (!semver) { 27 | return new Response("Invalid version", { status: 400 }); 28 | } 29 | 30 | if (!VERSIONS.includes(format(semver))) { 31 | return new Response("Version not found", { status: 404 }); 32 | } 33 | 34 | const url = `${BASE_URL}${format(semver)}/${path}`; 35 | const r = await fetch(url, { redirect: "manual" }); 36 | const response = new Response(r.body, r); 37 | response.headers.delete("content-encoding"); 38 | 39 | if (response.status === 404) { 40 | return new Response( 41 | "404: Not Found. The requested Fresh release or file do not exist.", 42 | { status: 404 }, 43 | ); 44 | } 45 | 46 | if (!response.ok) { 47 | response.headers.set("Content-Type", "text/plain"); 48 | return response; 49 | } 50 | 51 | const value = isHTML 52 | ? "text/plain" 53 | : contentTypes.get(extname(path)) ?? "text/plain"; 54 | response.headers.set("Content-Type", value); 55 | 56 | return response; 57 | }, 58 | }); 59 | 60 | export const config: RouteConfig = { 61 | routeOverride: "/@:version/:path*", 62 | }; 63 | -------------------------------------------------------------------------------- /www/routes/recipes/_layout.tsx: -------------------------------------------------------------------------------- 1 | import type { PageProps } from "fresh"; 2 | import Header from "../../components/Header.tsx"; 3 | 4 | export default function Layout({ Component }: PageProps) { 5 | return ( 6 | <> 7 |
8 | 9 |
10 | 11 |

12 | This route is used only for demo purposes;{" "} 13 | see the home page. 14 |

15 |
16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /www/routes/recipes/_middleware.ts: -------------------------------------------------------------------------------- 1 | import { define } from "../../utils/state.ts"; 2 | 3 | export const handler = define.middleware((ctx) => { 4 | ctx.state.noIndex = true; 5 | return ctx.next(); 6 | }); 7 | -------------------------------------------------------------------------------- /www/routes/recipes/lemon-honey-tea.tsx: -------------------------------------------------------------------------------- 1 | import { Partial } from "fresh/runtime"; 2 | import type { RouteConfig } from "fresh"; 3 | 4 | export const config: RouteConfig = { 5 | skipAppWrapper: true, 6 | skipInheritedLayouts: true, 7 | }; 8 | 9 | export const LemonHoneyTea = () => ( 10 | 11 |

Lemon-honey tea

12 |
    13 |
  • 1 cup boiling water
  • 14 |
  • ¼ tsp black tea
  • 15 |
  • 2 tsp honey
  • 16 |
  • 1 tsp lemon juice
  • 17 |
  • Lemon peel
  • 18 |
19 |
20 | ); 21 | 22 | export default LemonHoneyTea; 23 | -------------------------------------------------------------------------------- /www/routes/recipes/lemonade.tsx: -------------------------------------------------------------------------------- 1 | import { Partial } from "fresh/runtime"; 2 | import type { RouteConfig } from "fresh"; 3 | 4 | export const config: RouteConfig = { 5 | skipAppWrapper: true, 6 | skipInheritedLayouts: true, 7 | }; 8 | 9 | export const Lemonade = () => ( 10 | 11 |

Lemonade

12 |
    13 |
  • 1 ¾ cups white sugar
  • 14 |
  • 1 cup water
  • 15 |
  • 9 lemons
  • 16 |
  • 7 cups ice water
  • 17 |
  • Ice
  • 18 |
19 |
20 | ); 21 | 22 | export default Lemonade; 23 | -------------------------------------------------------------------------------- /www/routes/recipes/lemondrop.tsx: -------------------------------------------------------------------------------- 1 | import { Partial } from "fresh/runtime"; 2 | import type { RouteConfig } from "fresh"; 3 | 4 | export const config: RouteConfig = { 5 | skipAppWrapper: true, 6 | skipInheritedLayouts: true, 7 | }; 8 | 9 | export const LemonDrop = () => ( 10 | 11 |

Lemondrop Martini

12 |
    13 |
  • 2 oz vodka
  • 14 |
  • 3/4 oz triple sec
  • 15 |
  • 16 | 1 oz fresh lemon juice 17 |
  • 18 |
  • 3/4 oz simple syrup
  • 19 |
20 |
21 | ); 22 | 23 | export default LemonDrop; 24 | -------------------------------------------------------------------------------- /www/routes/update.tsx: -------------------------------------------------------------------------------- 1 | import { define } from "../utils/state.ts"; 2 | import VERSIONS from "../../versions.json" with { type: "json" }; 3 | 4 | export const handler = define.handlers({ 5 | GET({ req }) { 6 | const accept = req.headers.get("accept"); 7 | let path = "/docs/concepts/updating"; 8 | if (accept && !accept.includes("text/html")) { 9 | path = `https://deno.land/x/fresh@${VERSIONS[0]}/update.ts`; 10 | } 11 | return new Response(`Redirecting to ${path}`, { 12 | headers: { "Location": path }, 13 | status: 307, 14 | }); 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /www/static/docs/deno-deploy-gh-action.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/docs/deno-deploy-gh-action.jpg -------------------------------------------------------------------------------- /www/static/docs/fresh-partial-docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/docs/fresh-partial-docs.png -------------------------------------------------------------------------------- /www/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/favicon.ico -------------------------------------------------------------------------------- /www/static/fonts/FixelVariable.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/fonts/FixelVariable.woff2 -------------------------------------------------------------------------------- /www/static/fonts/FixelVariableItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/fonts/FixelVariableItalic.woff2 -------------------------------------------------------------------------------- /www/static/fresh-arrow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /www/static/gallery/banner-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/gallery/banner-chart.png -------------------------------------------------------------------------------- /www/static/gallery/banner-tabler-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/gallery/banner-tabler-icons.png -------------------------------------------------------------------------------- /www/static/gallery/grid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /www/static/gallery/hero-bg.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/gallery/hero-bg.webp -------------------------------------------------------------------------------- /www/static/google40caa9e535ae39e9.html: -------------------------------------------------------------------------------- 1 | google-site-verification: google40caa9e535ae39e9.html 2 | -------------------------------------------------------------------------------- /www/static/icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /www/static/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /www/static/logos/preact.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /www/static/logos/typescript.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /www/static/og-image.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/og-image.webp -------------------------------------------------------------------------------- /www/static/prism.css: -------------------------------------------------------------------------------- 1 | /* PrismJS 1.29.0 2 | https://prismjs.com/download.html#themes=prism-okaidia&languages=markup+css+clike+javascript */ 3 | code[class*="language-"], pre[class*="language-"] { 4 | color: #f8f8f2; 5 | background: 0 0; 6 | text-shadow: 0 1px rgba(0, 0, 0, 0.3); 7 | font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; 8 | font-size: 1em; 9 | text-align: left; 10 | white-space: pre; 11 | word-spacing: normal; 12 | word-break: normal; 13 | word-wrap: normal; 14 | line-height: 1.5; 15 | -moz-tab-size: 4; 16 | -o-tab-size: 4; 17 | tab-size: 4; 18 | -webkit-hyphens: none; 19 | -moz-hyphens: none; 20 | -ms-hyphens: none; 21 | hyphens: none; 22 | } 23 | pre[class*="language-"] { 24 | padding: 1em; 25 | margin: 0.5em 0; 26 | overflow: auto; 27 | border-radius: 0.3em; 28 | } 29 | :not(pre) > code[class*="language-"], pre[class*="language-"] { 30 | background: #272822; 31 | } 32 | :not(pre) > code[class*="language-"] { 33 | padding: 0.1em; 34 | border-radius: 0.3em; 35 | white-space: normal; 36 | } 37 | .token.cdata, .token.comment, .token.doctype, .token.prolog { 38 | color: #8292a2; 39 | } 40 | .token.punctuation { 41 | color: #f8f8f2; 42 | } 43 | .token.namespace { 44 | opacity: 0.7; 45 | } 46 | .token.constant, .token.deleted, .token.property, .token.symbol, .token.tag { 47 | color: #f92672; 48 | } 49 | .token.boolean, .token.number { 50 | color: #ae81ff; 51 | } 52 | .token.attr-name, 53 | .token.builtin, 54 | .token.char, 55 | .token.inserted, 56 | .token.selector, 57 | .token.string { 58 | color: #a6e22e; 59 | } 60 | .language-css .token.string, 61 | .style .token.string, 62 | .token.entity, 63 | .token.operator, 64 | .token.url, 65 | .token.variable { 66 | color: #f8f8f2; 67 | } 68 | .token.atrule, .token.attr-value, .token.class-name, .token.function { 69 | color: #e6db74; 70 | } 71 | .token.keyword { 72 | color: #66d9ef; 73 | } 74 | .token.important, .token.regex { 75 | color: #fd971f; 76 | } 77 | .token.bold, .token.important { 78 | font-weight: 700; 79 | } 80 | .token.italic { 81 | font-style: italic; 82 | } 83 | .token.entity { 84 | cursor: help; 85 | } 86 | -------------------------------------------------------------------------------- /www/static/showcase/Denosoar1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/Denosoar1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/Denosoar2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/Denosoar2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/MergePanic1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/MergePanic1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/MergePanic2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/MergePanic2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/Paquet1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/Paquet1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/Paquet2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/Paquet2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/adam-portfolio1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/adam-portfolio1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/adam-portfolio2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/adam-portfolio2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/ajvanegasv1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/ajvanegasv1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/ajvanegasv2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/ajvanegasv2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/andbounds1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/andbounds1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/andbounds2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/andbounds2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/aquavibes1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/aquavibes1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/aquavibes2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/aquavibes2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/awesome-fresh1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/awesome-fresh1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/awesome-fresh2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/awesome-fresh2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/balello1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/balello1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/balello2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/balello2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/battleship1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/battleship1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/battleship2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/battleship2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/cgpa-au-20211x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/cgpa-au-20211x.jpg -------------------------------------------------------------------------------- /www/static/showcase/cgpa-au-20212x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/cgpa-au-20212x.jpg -------------------------------------------------------------------------------- /www/static/showcase/cs2items1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/cs2items1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/cs2items2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/cs2items2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/d3nodata1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/d3nodata1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/d3nodata2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/d3nodata2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/deco.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deco.webp -------------------------------------------------------------------------------- /www/static/showcase/deno-artwork1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deno-artwork1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/deno-artwork2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deno-artwork2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/deno-diary1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deno-diary1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/deno-diary2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deno-diary2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/deno-jobs1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deno-jobs1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/deno-jobs2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deno-jobs2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/deno-saaskit1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deno-saaskit1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/deno-saaskit2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deno-saaskit2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/deno1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deno1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/deno2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/deno2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/denopaste1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/denopaste1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/denopaste2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/denopaste2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/dgaubert1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/dgaubert1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/dgaubert2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/dgaubert2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/diKnow1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/diKnow1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/diKnow2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/diKnow2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/echo-echo1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/echo-echo1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/echo-echo2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/echo-echo2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/evilmonkey19-cv1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/evilmonkey19-cv1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/evilmonkey19-cv2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/evilmonkey19-cv2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/festwithme1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/festwithme1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/festwithme2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/festwithme2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/filter-hn1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/filter-hn1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/filter-hn2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/filter-hn2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fondest1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fondest1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fondest2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fondest2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh-blog-system1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh-blog-system1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh-blog-system2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh-blog-system2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh-notion-blog1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh-notion-blog1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh-notion-blog2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh-notion-blog2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh-project-manager1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh-project-manager1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh-project-manager2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh-project-manager2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh-strapi1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh-strapi1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh-strapi2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh-strapi2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh-todo1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh-todo1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh-todo2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh-todo2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/fresh2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/fresh2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/grape-chat1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/grape-chat1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/grape-chat2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/grape-chat2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/guigui641x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/guigui641x.jpg -------------------------------------------------------------------------------- /www/static/showcase/guigui642x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/guigui642x.jpg -------------------------------------------------------------------------------- /www/static/showcase/hazn1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/hazn1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/hazn2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/hazn2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/hicoffee1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/hicoffee1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/hicoffee2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/hicoffee2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/hn1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/hn1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/hn2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/hn2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/imasparql-dd1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/imasparql-dd1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/imasparql-dd2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/imasparql-dd2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/javaminidoodle1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/javaminidoodle1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/javaminidoodle2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/javaminidoodle2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/jptchat1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/jptchat1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/jptchat2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/jptchat2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/jsr1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/jsr1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/jsr2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/jsr2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/kadode_portal1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/kadode_portal1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/kadode_portal2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/kadode_portal2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/kanji-academy1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/kanji-academy1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/kanji-academy2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/kanji-academy2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/kita1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/kita1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/kita2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/kita2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/ldkit1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/ldkit1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/ldkit2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/ldkit2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/learn-mandarin1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/learn-mandarin1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/learn-mandarin2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/learn-mandarin2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/liberchat1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/liberchat1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/liberchat2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/liberchat2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/link-maker1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/link-maker1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/link-maker2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/link-maker2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/linksapp1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/linksapp1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/linksapp2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/linksapp2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/living-pixel1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/living-pixel1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/living-pixel2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/living-pixel2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/localseostudio1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/localseostudio1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/localseostudio2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/localseostudio2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/m33t1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/m33t1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/m33t2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/m33t2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/melon1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/melon1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/melon2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/melon2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/merch1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/merch1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/merch2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/merch2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/mieszko1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/mieszko1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/mieszko2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/mieszko2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/miguel-rangel-site1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/miguel-rangel-site1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/miguel-rangel-site2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/miguel-rangel-site2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/moe-counter1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/moe-counter1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/moe-counter2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/moe-counter2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/mooxl1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/mooxl1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/mooxl2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/mooxl2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/openai-semantic-search1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/openai-semantic-search1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/openai-semantic-search2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/openai-semantic-search2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/optimem1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/optimem1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/optimem2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/optimem2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/pile-up1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/pile-up1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/pile-up2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/pile-up2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/pollify1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/pollify1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/pollify2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/pollify2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/ppaste1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/ppaste1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/ppaste2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/ppaste2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/rebstorm1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/rebstorm1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/rebstorm2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/rebstorm2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/rfui1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/rfui1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/rfui2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/rfui2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/teams-template1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/teams-template1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/teams-template2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/teams-template2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/text2audio1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/text2audio1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/text2audio2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/text2audio2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/thoth-doc1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/thoth-doc1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/thoth-doc2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/thoth-doc2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/ticoxs1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/ticoxs1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/ticoxs2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/ticoxs2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/uspb1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/uspb1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/uspb2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/uspb2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/videopoker-academy1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/videopoker-academy1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/videopoker-academy2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/videopoker-academy2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/virtualfreight1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/virtualfreight1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/virtualfreight2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/virtualfreight2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/webhook-manager1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/webhook-manager1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/webhook-manager2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/webhook-manager2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/wricord1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/wricord1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/wricord2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/wricord2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/wtfcongress1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/wtfcongress1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/wtfcongress2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/wtfcongress2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/yaml-to-ts1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/yaml-to-ts1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/yaml-to-ts2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/yaml-to-ts2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/ycrm1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/ycrm1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/ycrm2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/ycrm2x.jpg -------------------------------------------------------------------------------- /www/static/showcase/zhiblog1x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/zhiblog1x.jpg -------------------------------------------------------------------------------- /www/static/showcase/zhiblog2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denoland/fresh/b4c3ff8e9813f1530cade71288f0aa0034fcaa4d/www/static/showcase/zhiblog2x.jpg -------------------------------------------------------------------------------- /www/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | import plugin from "tailwindcss/plugin.js"; 3 | 4 | export default { 5 | content: [ 6 | "{routes,islands,components}/**/*.{ts,tsx}", 7 | ], 8 | plugins: [ 9 | plugin((api) => { 10 | api.addUtilities({ 11 | ".form-select-bg": { 12 | "background-image": 13 | `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3e%3cpath d='M7 7l3-3 3 3m0 6l-3 3-3-3' stroke='%239fa6b2' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e")`, 14 | "background-position": "right 0.5rem center", 15 | "background-size": "1.5em 1.5em", 16 | "background-repeat": "no-repeat", 17 | }, 18 | }); 19 | }), 20 | ], 21 | theme: { 22 | extend: { 23 | colors: { 24 | // Dark/light with Tailwind done right using CSS variables: 25 | "fresh": "hsla(var(--fresh))", 26 | "fresh-green": "hsla(var(--fresh-green))", 27 | 28 | "background-primary": "hsla(var(--background-primary))", 29 | "background-secondary": "hsla(var(--background-secondary))", 30 | "background-tertiary": "hsla(var(--background-tertiary))", 31 | "foreground-primary": "hsla(var(--foreground-primary))", 32 | "foreground-secondary": "hsla(var(--foreground-secondary))", 33 | "foreground-tertiary": "hsla(var(--foreground-tertiary))", 34 | "foreground-quaternary": "hsla(var(--foreground-quaternary))", 35 | 36 | "info": "hsla(var(--info))", 37 | }, 38 | }, 39 | }, 40 | } satisfies Config; 41 | -------------------------------------------------------------------------------- /www/telemetry.ts: -------------------------------------------------------------------------------- 1 | import { register } from "jsr:@deno/otel"; 2 | 3 | if (Deno.telemetry) register(); 4 | -------------------------------------------------------------------------------- /www/utils/screenshot.ts: -------------------------------------------------------------------------------- 1 | import { launch } from "astral"; 2 | import { Image } from "imagescript"; 3 | 4 | if (Deno.args.length !== 2) { 5 | throw new Error("Usage: screenshot "); 6 | } 7 | 8 | const [url, id] = Deno.args; 9 | const parsedUrl = new URL(url); 10 | if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") { 11 | throw new Error("Invalid URL"); 12 | } 13 | 14 | const browser = await launch(); 15 | const page = await browser.newPage(url); 16 | await page.waitForNetworkIdle(); 17 | const raw = await page.screenshot(); 18 | 19 | await browser.close(); 20 | 21 | // convert to jpeg 22 | const image2x = await Image.decode(raw); 23 | await Deno.writeFile( 24 | `./www/static/showcase/${id}2x.jpg`, 25 | await image2x.encodeJPEG(80), 26 | ); 27 | 28 | const image1x = image2x.resize(image2x.width / 2, Image.RESIZE_AUTO); 29 | await Deno.writeFile( 30 | `./www/static/showcase/${id}1x.jpg`, 31 | await image1x.encodeJPEG(80), 32 | ); 33 | -------------------------------------------------------------------------------- /www/utils/state.ts: -------------------------------------------------------------------------------- 1 | import { createDefine } from "fresh"; 2 | 3 | export interface State { 4 | title?: string; 5 | description?: string; 6 | ogImage?: string; 7 | noIndex?: boolean; 8 | } 9 | 10 | export const define = createDefine(); 11 | --------------------------------------------------------------------------------