diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 000000000..e5b6d8d6a --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/brave-baboons-talk.md b/.changeset/brave-baboons-talk.md new file mode 100644 index 000000000..fb31c265e --- /dev/null +++ b/.changeset/brave-baboons-talk.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +Rework `@solidjs/start/env` diff --git a/.changeset/calm-paths-pull.md b/.changeset/calm-paths-pull.md new file mode 100644 index 000000000..50a5bef17 --- /dev/null +++ b/.changeset/calm-paths-pull.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": minor +--- + +Fix path resolution on Windows diff --git a/.changeset/chilled-turkeys-leave.md b/.changeset/chilled-turkeys-leave.md new file mode 100644 index 000000000..c8f956bc6 --- /dev/null +++ b/.changeset/chilled-turkeys-leave.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +Fix multiple `Set-Cookie` headers being lost on redirect responses diff --git a/.changeset/clean-actors-jam.md b/.changeset/clean-actors-jam.md new file mode 100644 index 000000000..43f14253f --- /dev/null +++ b/.changeset/clean-actors-jam.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +import DevEnvironment and Rollup as type from vite diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 000000000..e23de5adc --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": ["landing-page", "tests"] +} diff --git a/.changeset/curly-waves-search.md b/.changeset/curly-waves-search.md new file mode 100644 index 000000000..d70ceb3dd --- /dev/null +++ b/.changeset/curly-waves-search.md @@ -0,0 +1,6 @@ +--- +"@solidjs/vite-plugin-nitro-2": minor +"@solidjs/start": minor +--- + +Updated dependencies. diff --git a/.changeset/eager-wings-crash.md b/.changeset/eager-wings-crash.md new file mode 100644 index 000000000..9a84befa8 --- /dev/null +++ b/.changeset/eager-wings-crash.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": minor +--- + +fix `body` being `undefined` for `onBeforeResponse` middlewares diff --git a/.changeset/eight-months-camp.md b/.changeset/eight-months-camp.md new file mode 100644 index 000000000..3767cae75 --- /dev/null +++ b/.changeset/eight-months-camp.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +Fixed CSS from shared chunks not being collected via the chunk name. diff --git a/.changeset/fifty-flies-yell.md b/.changeset/fifty-flies-yell.md new file mode 100644 index 000000000..550e66a80 --- /dev/null +++ b/.changeset/fifty-flies-yell.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": minor +--- + +fix text/html missing when ssr is false diff --git a/.changeset/fresh-eyes-bet.md b/.changeset/fresh-eyes-bet.md new file mode 100644 index 000000000..9c43bd2dc --- /dev/null +++ b/.changeset/fresh-eyes-bet.md @@ -0,0 +1,5 @@ +--- +"@solidjs/vite-plugin-nitro-2": minor +--- + +fix edge presets like netlify and cloudflare diff --git a/.changeset/funny-pandas-clean.md b/.changeset/funny-pandas-clean.md new file mode 100644 index 000000000..5c5c06007 --- /dev/null +++ b/.changeset/funny-pandas-clean.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +fix: clone request headers in single-flight to avoid mutating immutable headers diff --git a/.changeset/little-gifts-wave.md b/.changeset/little-gifts-wave.md new file mode 100644 index 000000000..5b6c43f79 --- /dev/null +++ b/.changeset/little-gifts-wave.md @@ -0,0 +1,7 @@ +--- +"@solidjs/start": patch +--- + +## Bump Seroval + +- version `1.4.1` diff --git a/.changeset/moody-hands-check.md b/.changeset/moody-hands-check.md new file mode 100644 index 000000000..fde7ef434 --- /dev/null +++ b/.changeset/moody-hands-check.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": minor +--- + +add `vite preview` support diff --git a/.changeset/nasty-ladybugs-trade.md b/.changeset/nasty-ladybugs-trade.md new file mode 100644 index 000000000..3da409ee4 --- /dev/null +++ b/.changeset/nasty-ladybugs-trade.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +Handle base url in API routes diff --git a/.changeset/plenty-geese-enter.md b/.changeset/plenty-geese-enter.md new file mode 100644 index 000000000..27c7c5457 --- /dev/null +++ b/.changeset/plenty-geese-enter.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": minor +--- + +seroval json mode diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 000000000..4d40c7739 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,23 @@ +{ + "mode": "pre", + "tag": "alpha", + "initialVersions": { + "@solidjs/start": "2.0.0-alpha.0", + "@solidjs/vite-plugin-nitro-2": "0.1.0" + }, + "changesets": [ + "brave-baboons-talk", + "calm-paths-pull", + "chilled-turkeys-leave", + "eager-wings-crash", + "eight-months-camp", + "fifty-flies-yell", + "fresh-eyes-bet", + "little-gifts-wave", + "moody-hands-check", + "nasty-ladybugs-trade", + "sharp-llamas-grab", + "tricky-hounds-relate", + "wicked-laws-bake" + ] +} diff --git a/.changeset/purple-taxes-join.md b/.changeset/purple-taxes-join.md new file mode 100644 index 000000000..db35aabe9 --- /dev/null +++ b/.changeset/purple-taxes-join.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +reload ssr server when new route files are created in dev diff --git a/.changeset/rare-canyons-travel.md b/.changeset/rare-canyons-travel.md new file mode 100644 index 000000000..fbad00f13 --- /dev/null +++ b/.changeset/rare-canyons-travel.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": minor +--- + +Add new directives plugin with shorter function IDs and inner declaration support diff --git a/.changeset/sharp-llamas-grab.md b/.changeset/sharp-llamas-grab.md new file mode 100644 index 000000000..3a9cf985a --- /dev/null +++ b/.changeset/sharp-llamas-grab.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +export server types from `/server` diff --git a/.changeset/smooth-foxes-taste.md b/.changeset/smooth-foxes-taste.md new file mode 100644 index 000000000..3dc17898e --- /dev/null +++ b/.changeset/smooth-foxes-taste.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": minor +--- + +feat: add `env:*` runtime environment variables support diff --git a/.changeset/tricky-hounds-relate.md b/.changeset/tricky-hounds-relate.md new file mode 100644 index 000000000..9369c796d --- /dev/null +++ b/.changeset/tricky-hounds-relate.md @@ -0,0 +1,5 @@ +--- +"@solidjs/vite-plugin-nitro-2": minor +--- + +needed to avoid weird issues like Cannot resolve "@tailwindcss/oxide-android-arm64/package.json" diff --git a/.changeset/wicked-laws-bake.md b/.changeset/wicked-laws-bake.md new file mode 100644 index 000000000..fe1b973b3 --- /dev/null +++ b/.changeset/wicked-laws-bake.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +Fixed virtual module CSS not being collected in vite dev. diff --git a/.editorconfig b/.editorconfig index 54c8a9183..de279a9ee 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,4 +5,6 @@ indent_style = space indent_size = 2 end_of_line = LF charset = utf-8 -insert_final_newline = true \ No newline at end of file +insert_final_newline = true +max_line_length = 100 +quote_type = double diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..0334717f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.html linguist-vendored diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..e9c06c805 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,9 @@ + + + + + + +## Overview + +... diff --git a/.github/ISSUE_TEMPLATE/01-bug.yml b/.github/ISSUE_TEMPLATE/01-bug.yml new file mode 100644 index 000000000..9511cea71 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01-bug.yml @@ -0,0 +1,68 @@ +name: Bug report ๐Ÿ› +description: Create a bug report for SolidStart. +labels: ["bug", "needs triage"] +title: "[Bug?]: " +body: + - type: markdown + attributes: + value: | + Please provide a searchable summary of the issue in the title above โฌ†๏ธ. + + Thanks for contributing by creating an issue! โค๏ธ + - type: checkboxes + attributes: + label: Duplicates + description: Please [search the history](https://github.com/solidjs/solid-start/issues) to see if an issue already exists for the same problem. + options: + - label: I have searched the existing issues + required: true + - type: checkboxes + attributes: + label: Latest version + description: We roll bug fixes, performance enhancements, and other improvements into new releases. + options: + - label: I have tested the latest version + required: true + - type: textarea + attributes: + label: Current behavior ๐Ÿ˜ฏ + description: Describe what happens instead of the expected behavior. + - type: textarea + attributes: + label: Expected behavior ๐Ÿค” + description: Describe what should happen. + - type: textarea + attributes: + label: Steps to reproduce ๐Ÿ•น + description: | + Provide a link to a live example (you can use codesandbox.io) and an unambiguous set of steps to reproduce this bug. + Include code to reproduce, if relevant (which it most likely is). + + :bangbang:   Issues that we can't reproduce will be closed. :bangbang: + value: | + Steps: + + 1. + 2. + 3. + 4. + - type: textarea + attributes: + label: Context ๐Ÿ”ฆ + description: What are you trying to accomplish? How has this issue affected you? Providing context helps us come up with a solution that is more useful in the real world. + - type: textarea + attributes: + label: Your environment ๐ŸŒŽ + description: Please paste the output of running whatever the command is for your environment. + placeholder: | + System: + OS: Linux 5.10 Debian GNU/Linux 9 (stretch) + CPU: (8) arm64 + Binaries: + Node: 20.0.0 - /usr/local/bin/node + Yarn: 3.0.0 - /usr/local/bin/yarn + npm: 9.8.0 - /usr/local/bin/npm + pnpm: 9.0.0 - /usr/local/bin/pnpm + npmPackages: + @solidjs/start: 1.0.0 => 1.0.0 + render: shell diff --git a/.github/ISSUE_TEMPLATE/02-feature.yml b/.github/ISSUE_TEMPLATE/02-feature.yml new file mode 100644 index 000000000..2198d4e2e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02-feature.yml @@ -0,0 +1,42 @@ +name: Feature request ๐Ÿ’„ +description: Suggest a new idea for SolidStart. +labels: ["enhancement", "needs triage"] +title: "[Feature?]: " +body: + - type: checkboxes + attributes: + label: Duplicates + description: Please [search the history](https://github.com/solidjs/solid-start/issues) to see if an issue already exists for the same problem. + options: + - label: I have searched the existing issues + required: true + + - type: checkboxes + attributes: + label: Latest version + description: We roll bug fixes, performance enhancements, and other improvements into new releases. + options: + - label: I have tested the latest version + required: true + + - type: markdown + attributes: + value: | + Please provide a searchable summary of the issue in the title above โฌ†๏ธ. + + Thanks for contributing by creating an issue! โค๏ธ + + - type: textarea + attributes: + label: Summary ๐Ÿ’ก + description: Describe how it should work. + + - type: textarea + attributes: + label: Examples ๐ŸŒˆ + description: Provide a link to the Solid Start specification, other implementations, or screenshots of the expected behavior. + + - type: textarea + attributes: + label: Motivation ๐Ÿ”ฆ + description: What are you trying to accomplish? How has the lack of this feature affected you? Providing context helps us come up with a solution that is more useful in the real world. diff --git a/.github/ISSUE_TEMPLATE/03-question.yml b/.github/ISSUE_TEMPLATE/03-question.yml new file mode 100644 index 000000000..10fa00688 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03-question.yml @@ -0,0 +1,27 @@ +name: "Questions / Help ๐Ÿ’ฌ" +description: If you have questions, please check the Discussions tab +title: "[Please read the message below]" +labels: [":speech_balloon: Question"] +body: + - type: markdown + attributes: + value: | + ## Questions and Help ๐Ÿ’ฌ + + This issue tracker is reserved for bug reports and feature proposals. + + For anything else, such as questions or getting help, please see: + + - [The Discussion Q&A page](https://github.com/solidjs/solid-start/discussions/categories/q-a) + - [All Discussions](https://github.com/solidjs/solid-start/discussions) + - [SolidJS Discord](https://discord.gg/solidjs) + - type: checkboxes + id: no-post + attributes: + label: | + Please do not submit this issue. + description: | + :bangbang:   This issue will be closed. :bangbang: + options: + - label: I understand + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..aea628d95 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,4 @@ +contact_links: + - name: "SolidJS Discord" + url: https://discord.gg/solidjs + about: For questions and suggestions, please joins us on discord! diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..f80cd347f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,16 @@ +## PR Checklist + +Please check if your PR fulfills the following requirements: + +- [ ] Addresses an existing open issue: fixes #000 +- [ ] Tests for the changes have been added (for bug fixes / features) + +## What is the current behavior? + + + +## What is the new behavior? + +## Other information + + diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 000000000..9d5ef9478 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,25 @@ +Thanks for helping make Solid safe for everyone. + +# Security + +SolidJS takes the security of our software seriously, including all of the open-source code repositories managed through [this GitHub organization](https://github.com/solidjs). + +## Reporting a Vulnerability + +**If you think you've found a security issue, please DO NOT report, discuss, or describe it on Discord or GitHub.** + +**All security-related issues, concerns, and problems must be reported via email to: security@solidjs.com** + +Please include everything necessary to reproduce the problem when sending over information, including an example repository on StackBlitz or GitHub. Please don't add explicit details about the security issue you are reporting in any of the repository's contents. + +**_This is detrimental to the safety of all SolidStart users. No exceptions._** + +## Embargo Policy + +SolidJS's Security Team members must share information only within the Solid Core and Security teams on a need-to-know basis to fix the related issue in Solid. The information members and others receive thorough participation in this group must not be made public, shared, or even hinted otherwise, except with prior explicit approval (which shall be handled on a case-by-case basis). This holds true until the agreed-upon public disclosure date/time is satisfied. + +As a clarifying example, this policy forbids Solid Security members from sharing list information with their employers; unless prior arrangements have been made directly with an employer. + +In the unfortunate event that you share the information beyond what is allowed by this policy, you must urgently inform the Solid Security Team of exactly what information leaked and to whom, as well as the steps that will be taken to prevent future leaks. + +**Repeated offenses may lead to the removal from the Security or Solid team.** diff --git a/.github/workflows/close-issue.yml b/.github/workflows/close-issue.yml new file mode 100644 index 000000000..bb0960244 --- /dev/null +++ b/.github/workflows/close-issue.yml @@ -0,0 +1,19 @@ +# CronJob +name: โฑ๏ธ Issue Close Require + +on: + schedule: + - cron: "0 0 * * *" + +jobs: + close-issues: + if: github.repository == 'solidjs/solid-start' + runs-on: ubuntu-latest + steps: + - name: needs reproduction + uses: actions-cool/issues-helper@v3 + with: + actions: "close-issues" + token: ${{ secrets.GITHUB_TOKEN }} + labels: "needs reproduction" + inactive-day: 3 diff --git a/.github/workflows/cr.yml b/.github/workflows/cr.yml new file mode 100644 index 000000000..8fc64abcc --- /dev/null +++ b/.github/workflows/cr.yml @@ -0,0 +1,45 @@ +name: โšก๏ธ Continuous Releases + +on: + push: + branches: + - main + - 1.x + merge_group: + pull_request: + +jobs: + cr: + name: "โšก๏ธ Continuous Releases" + + strategy: + fail-fast: false + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v3 + + - name: Use Node.js from .nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + registry-url: "https://registry.npmjs.org" + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build Packages + run: | + pnpm run build + pnpm rewrite-exports + + - name: Release Packages + # remove the compat flag until all packages are available on npm + # run: | + # pnpm dlx pkg-pr-new@0.0 publish './packages/*' --template './examples/*' --compact + run: | + pnpm dlx pkg-pr-new@0.0 publish './packages/*' diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml deleted file mode 100644 index 5adb1bbf1..000000000 --- a/.github/workflows/deploy-docs.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: ๐Ÿ“œ Docs - -on: - push: - branches: - - main - -env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - -jobs: - docs: - name: "๐Ÿ“œ Deploy Docs" - - strategy: - fail-fast: false - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - uses: pnpm/action-setup@v2.2.2 - with: - version: 7 - - - name: Use Node.js 16 - uses: actions/setup-node@v3 - with: - node-version: 16 - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build docs - run: pnpm run docs:build - - - run: npx wrangler publish diff --git a/.github/workflows/dist-typecheck.yml b/.github/workflows/dist-typecheck.yml new file mode 100644 index 000000000..75108e7c2 --- /dev/null +++ b/.github/workflows/dist-typecheck.yml @@ -0,0 +1,40 @@ +name: Type Check Distribution + +on: + pull_request: ~ + push: + branches: + - main + +jobs: + typecheck-dist: + name: Check ${{ matrix.package }} distributed types + runs-on: ubuntu-latest + strategy: + matrix: + ## to add other packages from the monorepo, add them to the matrix + package: [start] + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - name: Use Node.js from nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + registry-url: "https://registry.npmjs.org" + cache: "pnpm" + + - name: Install Dependencies + run: pnpm i --frozen-lockfile + + - name: Build ${{ matrix.package }} package and dependencies + # build the package and all its dependencies + run: pnpm --filter ${{ matrix.package }}... build + + - run: pnpm rewrite-exports + + - name: Check types with @arethetypeswrong/cli + run: pnpm --filter ${{ matrix.package }} typecheck:dist diff --git a/.github/workflows/issue-labelled.yml b/.github/workflows/issue-labelled.yml new file mode 100644 index 000000000..47f0d37e3 --- /dev/null +++ b/.github/workflows/issue-labelled.yml @@ -0,0 +1,30 @@ +name: ๐Ÿ”– Issue Labelled + +on: + issues: + types: [labeled] + +jobs: + reply-labeled: + if: github.repository == 'vitejs/vite' + runs-on: ubuntu-latest + steps: + - name: contribution welcome + if: github.event.label.name == 'contribution welcome' || github.event.label.name == 'help wanted' || github.event.label.name == 'good first issue' + uses: actions-cool/issues-helper@v3 + with: + actions: "remove-labels" + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.issue.number }} + labels: "pending triage, needs reproduction" + + - name: needs reproduction + if: github.event.label.name == 'needs reproduction' + uses: actions-cool/issues-helper@v3 + with: + actions: "create-comment, remove-labels" + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.issue.number }} + body: | + Hello @${{ github.event.issue.user.login }}. Please provide a [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) using a GitHub repository or [StackBlitz](https://stackblitz.com/). Issues marked with `needs reproduction` will be closed if they have no activity within 3 days. + labels: "pending triage" diff --git a/.github/workflows/issues.yml b/.github/workflows/issues.yml new file mode 100644 index 000000000..66d7a943f --- /dev/null +++ b/.github/workflows/issues.yml @@ -0,0 +1,15 @@ +name: 'Close issues' + +on: + issues: + types: [labeled] + +jobs: + questions: + runs-on: ubuntu-latest + steps: + - name: Close Issue + uses: peter-evans/close-issue@v3 + if: "${{ github.event.label.name == ':speech_balloon: Question' }}" + with: + comment: Please note this issue tracker is not a help forum. We recommend using [Discussions](https://github.com/solidjs/solid-start/discussions/categories/q-a) for questions. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..e07798c84 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,41 @@ +name: Release + +on: + push: + branches: + - 1.x + - main + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + + - uses: pnpm/action-setup@v3 + + - name: Use Node.js from nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + registry-url: "https://registry.npmjs.org" + cache: "pnpm" + + - name: Install Dependencies + run: pnpm i --frozen-lockfile + + - name: Create Release Pull Request or Publish to npm + id: changesets + uses: changesets/action@v1 + with: + publish: pnpm run release + title: "chore: release" + commit: "chore: release" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 718945b96..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,103 +0,0 @@ -name: ๐Ÿงช Test - -on: - push: - branches: - - main - - dev - - release-* - tags-ignore: - - v* - paths-ignore: - - "docs/**" - - "docs.root.tsx" - - "components/**" - - "**/README.md" - pull_request: - paths-ignore: - - "docs/**" - - "**/*.md" - -env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CF_ACCOUNT_TOKEN }} - CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} - -jobs: - integration: - name: "๐Ÿ‘€ ${{ matrix.adapter }} (os: ${{ matrix.os }}, node: ${{ matrix.node-version }})" - - strategy: - fail-fast: false - matrix: - node-version: [16] - adapter: - - solid-start-node - - solid-start-cloudflare-workers - - solid-start-cloudflare-pages - - solid-start-deno - os: - - ubuntu-latest - # - macos-latest - - windows-latest - include: - - os: ubuntu-latest - playwright_binary_path: ~/.cache/ms-playwright - # - os: macos-latest - # playwright_binary_path: ~/Library/Caches/ms-playwright - - os: windows-latest - playwright_binary_path: '~\\AppData\\Local\\ms-playwright' - - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v2 - - - uses: pnpm/action-setup@v2.2.2 - with: - version: 7 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Use Deno - if: matrix.adapter == 'solid-start-deno' - uses: denoland/setup-deno@v1 - with: - deno-version: v1.x - - - name: ๐Ÿ•ต๏ธโ€โ™‚๏ธ Get current Playwright version - id: playwright-version - shell: bash - run: | - playwright_version=1.23.4 - echo "::set-output name=version::${playwright_version}" - - - name: ๐Ÿค– Cache Playwright binaries - uses: actions/cache@v3 - id: playwright-cache - with: - path: ${{ matrix.playwright_binary_path }} - key: ${{ runner.os }}-${{ runner.arch }}-cache-playwright-${{ steps.playwright-version.outputs.version }} - - - name: ๐Ÿ–จ๏ธ Playwright info - shell: bash - run: | - echo "OS: ${{ matrix.os }}" - echo "Playwright version: ${{ steps.playwright-version.outputs.version }}" - echo "Playwright install dir: ${{ matrix.playwright_binary_path }}" - echo "Cache key: ${{ runner.os }}-${{ runner.arch }}-cache-playwright-${{ steps.playwright-version.outputs.version }}" - echo "Cache hit: ${{ steps.playwright-cache.outputs.cache-hit == 'true' }}" - - - name: ๐Ÿ“ฅ Install Playwright - if: steps.playwright-cache.outputs.cache-hit != 'true' - run: pnpm --filter solid-start-tests install:playwright - - - name: ๐Ÿ‘€ Run Integration Tests - env: - START_ADAPTER: ${{ matrix.adapter }} - run: npm run test diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..0f130e433 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,44 @@ +name: ๐Ÿงช Tests + +on: + workflow_dispatch: + # Add remaining triggers + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + tests: + name: "๐Ÿงช Run All Tests" + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v4 + + - name: Use Node.js from nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + registry-url: "https://registry.npmjs.org" + cache: "pnpm" + + - name: Install project dependencies + run: pnpm i + + - name: Install Playwright Browsers + run: pnpm --filter tests exec playwright install chromium + + - name: Build SolidStart + run: pnpm --filter @solidjs/start build + + - name: Build Test Project + run: pnpm --filter tests build + + - name: Run all apps/tests (Unit, Node, Browser UI, and E2E) + run: pnpm --filter tests run test:all + + # The @solidjs/start package currently has no tests, so we are skipping this step. + # Uncomment if tests are added to the @solidjs/start package. + # - name: Run @solidjs/start unit tests + # run: pnpm --filter @solidjs/start test:ci diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 0388a248a..5233232b6 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -4,37 +4,56 @@ on: push: branches: - main + - 1.x - dev - release-* tags-ignore: - v* - paths-ignore: - - "docs/**" - - "docs.root.tsx" - - "components/**" - - "**/README.md" + pull_request: - paths-ignore: - - "docs/**" - - "**/*.md" + branches: + - main + - 1.x + - dev + - release-* jobs: + filter-changes: + runs-on: ubuntu-latest + outputs: + should_skip: ${{ steps.changes.outputs.landing_page }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Get changed files + id: changes + uses: dorny/paths-filter@v2 + with: + filters: | + landing_page: + - 'docs/**' + - "docs.root.tsx" + - "components/**" + - "**/README.md" typecheck: name: "๐Ÿ‘€ Typecheck" + needs: filter-changes + if: needs.filter-changes.outputs.should_skip != 'true' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2.2.2 - with: - version: 7 + - uses: pnpm/action-setup@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + - name: Use Node.js from .nvmrc + uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} + node-version-file: ".nvmrc" + registry-url: "https://registry.npmjs.org" cache: "pnpm" - name: Install dependencies diff --git a/.gitignore b/.gitignore index 36fb5de80..1a82eb615 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,10 @@ coverage/ types/ .turbo +.nitro +.output +.vinxi -packages/create-solid/bin *.log playground @@ -24,6 +26,7 @@ node_modules .tmp test/playwright-report +tests/server-function/cypress/screenshots # Temp gitignore @@ -41,3 +44,14 @@ netlify # miniflare cache .mf .vercel + +vite.config.ts.timestamp* + +.nitro +.output + +.data +tsconfig.tsbuildinfo + +apps/tests/**/test-results +.solid-start diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..e2228113d --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22.19.0 diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 000000000..45c63abd9 --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxfmt/configuration_schema.json", + "tabWidth": 2, + "useTabs": false, + "endOfLine": "lf", + "trailingComma": "all", + "semi": true, + "singleQuote": false, + "arrowParens": "avoid", + "printWidth": 100 +} diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 6aeb7ea15..000000000 --- a/.prettierrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "trailingComma": "none", - "tabWidth": 2, - "semi": true, - "singleQuote": false, - "arrowParens": "avoid", - "printWidth": 100 -} diff --git a/.stackblitzrc b/.stackblitzrc index bfea831bf..aa8c6f31a 100644 --- a/.stackblitzrc +++ b/.stackblitzrc @@ -1,3 +1,3 @@ { - "startCommand": "chmod +x ./packages/start/bin.cjs && pnpm run docs:dev" + "startCommand": "chmod +x ./packages/start/bin.cjs && pnpm run lp:dev" } diff --git a/.vscode/settings.json b/.vscode/settings.json index e37a838ff..cb731fb60 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,14 @@ { "editor.codeActionsOnSave": { - "source.organizeImports": true + // "source.organizeImports": "explicit" }, - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "editor.formatOnSave": true, + "editor.defaultFormatter": "oxc.oxc-vscode", + "[typescript]": { + "editor.defaultFormatter": "oxc.oxc-vscode" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "oxc.oxc-vscode" + } } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e6f515c43..a882e9714 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,17 +1,84 @@ # Contributing -1. Clone the repository - `git clone https://github.com/solidjs/solid-start.git` -2. Install dependencies - `pnpm install` -3. Run an example - `pnpm --filter example-hackernews run dev` -4. Make changes and check if things work in examples -5. Add integration tests in `test`, if appropriate -6. Run tests locally - - Setup playwright: `pnpm --filter solid-start-tests install:playwright` - - Run all tests: `pnpm run test:all` - -## Requirements - -1. Node.js: ^16.13.0 +Thank you for your interest in contributing to **SolidStart**. +We welcome contributions including bug fixes, feature enhancements, documentation improvements, and more. + +## Creating a Template + +We do not maintain official templates and integrations in this monorepo. +Instead, please head over to [solidjs/templates](https://github.com/solidjs/templates) to submit your contribution. + +## Documentation + +We always want help and creative ways of explaining how to take the best out of SolidStart. +Alas, this is not the right place to do it, please head over to [SolidDocs](https://github.com/solidjs/solid-docs) and contribute to the official documentation! + +## Feature Request + +> [!IMPORTANT] +> Do not create a PR without prior discussion in an issue + +If there's a new feature you'd like to request you can: + +1. Create an issue and make your pitch. Be sure to explain the value proposition in a way that will benefit most users. + +2. If it's a more general concept, feel free to open a [Discussion](https://github.com/solidjs/solid-start/discussions) in the **Idea** category. + +A new **primitive** follows the same criteria as issues, please create an issue for it to be discussed beforehand. + +Primitives that depend on multiple external dependencies and 3rd party integrations are generally not a good fit to live inside this monorepo, we still welcome you to create it and share with the ecosystem. +Reach out in a [Discussion](https://github.com/solidjs/solid-start/discussions) in the **showcase** section and we'll amplify as much as we can! + +## Found a Bug + +If you believe you found a bug, we appreciate you creating an issue. +Issues without a reproduction or PR link will be **automatically closed**. + +To speed up triaging, we recommend 2 strategies: + +### Minimal Reproduction + +Create a **minimal** reproduction either in a remote IDE or in an open-source repository and add a link to your issue. + +We recommend using the `create-solid` package with the **basic** setting. + +| Package Manager | Command | +| --------------- | ---------------------------------------- | +| pnpm | `pnpm create solid@latest -st basic` | +| npm | `npm create solid@latest -- -st basic` | +| yarn | `yarn create solid -st basic` | +| bun | `bun create solid@latest --s --t basic` | +| deno | `deno run -A npm:create-solid -st basic` | + +### Failing Test PR + +You can also fork this repository and go to `apps/tests`. +There we have an app with all default configurations and many routes. +Create a new route, a Vitest or Playwright assertion (as appropriate) to it and open a PR with the failing test-case. + +Once the PR is there, **create an issue** and link the PR (mention the PR as you'd mention a person in the issue description and vice versa). + +##### On testing + +- If what you'd like to change needs e2e testing (i.e. you need a working build to test your feature), use playwright (see the `/app/tests/e2e` directory for examples). +- If what you'd like to change is specific to a component, function (i.e. you need a unit test), use Vitest. You can find examples in the `/app/tests/` directory, look for the .tests.ts/.test.tsx files. + - Note: Vitest is also set-up to test individual components - have a look at `/app/tests/routes/(basic).browser.test.tsx` for an example. + +#### Testing conventions: + +- For e2e test, simply place them in the `apps/tests/e2e` directory. The project is configured to run anything found in that directory via playwright as an e2e test. +- For unit tests, co-locate them in the same place as the component or function they test: + - E.g. If you're testing `/app/tests/MyComponent.tsx`, create a file named `/app/tests/MyComponent.test.browser.tsx` in the same directory. Note the `.browser` part - that's important to tell Vitest that this test should run in a browser environment. + - For server-side unit tests, use the same placement conventions as described for components, but create a file named `/app/tests/myfeature.test.server.ts` in the same directory. Using `.server` in the filename tells Vitest that this test should run in a node environment. + +> [!IMPORTANT] +> Mark the **allow edit by the maintainers** so we can more easily investigate the failing test and propose a fix. Otherwise we may need to close your PR and cherry-pick your commit. + +### Formatting your code + +We have a set of rules defined in the `.editorconfig` and `.oxfmtrc.json` files. Please format your code before opening a PR, so that we keep the codebase consistent. Regardless of what editor you use, running `pnpm format` will format your code according to our rules. + +--- + +If you have read all the way here, you're already a champ! ๐Ÿ† +Thank you. diff --git a/README.md b/README.md index ccab6e649..18c644e35 100644 --- a/README.md +++ b/README.md @@ -1,364 +1,146 @@ -

- Solid Docs -

- -# SolidStart - -This is the home of the Solid app framework. This is still a **work in progress**. Many features are missing or incomplete. Experimental status does not even mean beta status. Patch releases will break everything. - -- File-system based routing -- Supports all rendering modes: - - Server-side rendering (SSR) - - Streaming SSR - - Client-side rendering (CSR) - - Static Site Generation (SSG) -- Streaming -- Build optimizations with Code splitting, tree shaking and dead code elimination -- API Routes -- Built on Web standards like Fetch, Streams, and WebCrypto -- Adapters for deployment to all popular platforms -- CSS Modules, SASS/SCSS Support -- TypeScript-first - -### Getting started +
-```bash -mkdir my-app -cd my-app -npm init solid@latest -npm install -npm run dev -``` - -### Development - -The monorepo uses `pnpm` as the package manager. To install `pnpm`, run the following command in your terminal. - -```bash -npm install -g pnpm -``` - -Run `pnpm install` to install all the dependencies for the packages and examples in your monorepo. - -
-

Monorepo & project.json "workspace" support

- -If you are using Solid Start within a monorepo that takes advantage of the `package.json` `"workspaces"` property (e.g. [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/)) with hoisted dependencies (the default for yarn), you must include `solid-start` within the optional `"nohoist"` (for yarn v2 or higher, see further down for instructions) workspaces property. - -- _In the following, "workspace root" refers to the root of your repository while "project root" refers to the root of a child package within your repository_ - -For example, if specifying `"nohoist"` options from the workspace root (i.e. for all packages): - -```jsonc -// in workspace root -{ - "workspaces": { - "packages": [ - /* ... */ - ], - "nohoist": ["**/solid-start"] - } -} -``` - -If specifying `"nohoist"` options for a specific package using `solid-start`: +[![Banner](https://assets.solidjs.com/banner?project=Start&type=core)](https://github.com/solidjs) -```jsonc -// in project root of a workspace child -{ - "workspaces": { - "nohoist": ["solid-start"] - } -} -``` - -Regardless of where you specify the `nohoist` option, you also need to include `solid-start` as a `devDependency` in the child `package.json`. - -The reason why this is necessary is because `solid-start` creates an `index.html` file within your project which expects to load a script located in `/node_modules/solid-start/runtime/entry.jsx` (where `/` is the path of your project root). By default, if you hoist the `solid-start` dependency into the workspace root then that script will not be available within the package's `node_modules` folder. - -**Yarn v2 or higher** +[![Version](https://img.shields.io/npm/v/@solidjs/start.svg?style=for-the-badge&color=blue&logo=npm)](https://npmjs.com/package/@solidjs/start) +[![Downloads](https://img.shields.io/npm/dm/@solidjs/start.svg?style=for-the-badge&color=green&logo=npm)](https://npmjs.com/package/@solidjs/start) +[![Stars](https://img.shields.io/github/stars/solidjs/solid-start?style=for-the-badge&color=yellow&logo=github)](https://github.com/solidjs/solid-start) +[![Discord](https://img.shields.io/discord/722131463138705510?label=join&style=for-the-badge&color=5865F2&logo=discord&logoColor=white)](https://discord.com/invite/solidjs) +[![Reddit](https://img.shields.io/reddit/subreddit-subscribers/solidjs?label=join&style=for-the-badge&color=FF4500&logo=reddit&logoColor=white)](https://reddit.com/r/solidjs) -The `nohoist` option is no longer available in Yarn v2+. In this case, we can use the `installConfig` property in the `package.json` (either workspace package or a specific project package) to make sure our deps are not hoisted. +
-```jsonc -// in project root of a workspace child -{ - "installConfig": { - "hoistingLimits": "dependencies" - } -} -``` - - +- For building apps with SolidStart, check the [package README](/packages/start/README.md) and our [official docs](https://docs.solidjs.com/solid-start) +- For contributing to codebase, check [CONTRIBUTING.md](/CONTRIBUTING.md) +- For creating a new template, please head over to [solidjs/templates](https://github.com/solidjs/templates) -## Changelog +> [!IMPORTANT] +> This is the branch for the SolidStart 2.0.0-alpha that is currently under heavy development. +> +> Current SolidStart is maintained at [`1.x`](https://github.com/solidjs/solid-start/tree/1.x). -### [0.1.6] +## Prerequisites -Renamed API Routes exports from lower case to upper case method names to match closely how people see those functions in the spec and in usage. +- **Node.js**: Use the version specified in `.nvmrc`. To manage multiple versions across your system, we recommend a version manager such as [fnm](https://github.com/Schniz/fnm), or another of your choice. +- **pnpm**: Install globally via `npm install -g pnpm`. Or let **Corepack** handle it in the setup step below. +- **Git**: Ensure Git is installed for cloning and managing the repository. -```diff -- export function get() { -+ export function GET() { - return new Response(); -} +## Monorepo Structure -- export function post() { -+ export function POST() { +SolidStart is a pnpm-based monorepo with nested workspaces. Key directories include: - return new Response(); -} +- **`packages/start`**: The core `@solidjs/start` package. +- **`apps/landing-page`**: The official landing page. +- **`apps/tests`**: Unit and end-to-end (E2E) tests using Vitest and Playwright. +- **`apps/fixtures`**: Fixture projects for testing. -- export function patch() { -+ export function PATCH() { - return new Response(); -} +Use pnpm filters (e.g. `pnpm --filter @solidjs/start ...`) to target specific packages. -- export function del() { -+ export function DELETE() { - return new Response(); -} -``` +## Local Setup -### [0.1.0-alpha.104] +1. Clone the repository -Changed grouped routes from `__name` syntax to `(name)`. + ```bash + git clone https://github.com/solidjs/solid-start.git + cd solid-start + ``` -### [0.1.0-alpha.103] +2. Enable the correct pnpm version specified in package.json -Changed special compiled functions like `server`, `createServerData`, `createServerAction$`, `createServerMultiAction$`. to have a postfix `$` to indicate their special compiled (hoisted behavior). + ```bash + corepack enable + ``` -Also moved the optional first argument of `createServerData$` under `key` option. While this hides a very important option it makes the signatures more similar, so it is clear it is the main (first) function that is running on the server. +3. Install dependencies -```js -const data = createServerData$( - async pathname => { - let mod = mods[`./docs${pathname}.mdx`] ?? mods[`./docs${pathname}.md`]; - return mod.getHeadings().filter(h => h.depth > 1 && h.depth <= 3); - }, - { - key: () => path.pathname - } -); -``` + ```bash + pnpm dedupe + ``` -### [0.1.0-alpha.??] - Moving towards beta + (`pnpm dedupe` will install dependencies _and_ clean the lockfile from duplicates, useful for preventing conflicts). -
-

vite.config.ts

+4. Build all packages and the landing page + ```bash + pnpm run build:all + ``` -```diff -- import solid from 'solid-start'; -+ import solid from 'solid-start/vite'; -import { defineConfig } from 'vite'; +If you encounter issues (e.g. missing `node_modules`), clean the workspace -export default defineConfig({ - plugins: [solid()] -}) -``` - -#### Why? - -We wanted to use the main entry point of `solid-start` for use within the app where you are spending most of your time. And for the `vite` config, we use the `solid-start/vite` entrypoint. -
- -
-

entry-server.tsx

- -```diff -import { createHandler, renderAsync, StartServer } from "solid-start/entry-server"; - -- export default createHandler(renderAsync(context => )); -+ export default createHandler(renderAsync(event => )); -``` - -#### Why? - -The prop received by `StartServer`, and given to you by `createHandler` is called `event` instead of `context`. It represents a `PageEvent` which is a `FetchEvent` that the server decided should be rendered by our components as a `Page`. We adopted the `event` terminology to represent the input that our server handlers received. - -For example, the input to our top-level server handler is a `FetchEvent`. It can then be routed to a server function and be passed as a `ServerFunctionEvent` or to an API Endpoint as an `ApiEvent`. This terminology is adopted from the ServiceWorker API and Cloudflare Workers API. - -
- -
-

entry-client.tsx

- -If you were using SSR: - -```diff -- import { hydrate } from "solid-js"; -- import { StartClient } from "solid-start/entry-client"; -+ import { mount, StartClient } from "solid-start/entry-client"; - -- hydrate(() => , document); -+ mount(() => , document); -``` - -If you were not using SSR and rendering your app client-side: - -```diff -- import { render } from "solid-js"; -- import { StartClient } from "solid-start/entry-client"; -+ import { mount, StartClient } from "solid-start/entry-client"; - -- render(() => , document.body); -+ mount(() => , document); -``` - -#### Why? - -Earlier, you called `hydrate(document)` or `render(document.body)` here based on what kind of rendering mode you had selected and whether you had SSR turned on. We felt this was slightly annoying to change if you wanted to switch between the modes and error prone if you are not careful and end up passing `document` to `render` instead. - -We still wanted to expose `entry-client.tsx` to the user so that they can take over and do their own thing here if they want. We made a helper function called `mount` that embeds the logic for deciding how to interact with the app we get from the server, be it `hydrate` or `render`. - -
- -
-

root.tsx

- -```diff -// @refresh reload -import { Suspense } from "solid-js"; -- import { Meta, Link, Routes, Scripts } from "solid-start/root"; -+ import { FileRoutes, Scripts, Html, Head, Body, Routes, Meta, ErrorBoundary, A } from "solid-start"; - -export default function Root() { - return ( -- -+ -- -+ - -- -+ -- -+ - -- // already exists inside `Head` -- // already exists inside `Head` - -- -+ -- -+ - - - Index - About -- -+ -+ -+ - - - -- -+ -- -+ - ); -} -``` - -#### Why? - -We changed how we declare our routes to make it more flexible. Earlier we gave you a `Routes` component from `solid-start` that was equivalent to rendering a `Routes` from `@solidjs/router` (yeah we know its confusing, that's why we are changing it) and filling it with the routes from the file system. The opt-in to the file-system routing was all-in or nothing. - -You didn't have an opportunity to add more `Route`s. We now export `FileRoutes` from `solid-start` that represents the route config based on the file-system. It is meant to be passed to the `Routes` component from `solid-start` or wherever you want to use the file-system routes config. - -- You can use it together with other `Route` components. - -```tsx - - - - -``` - -- Also for quickly starting an app without creating a bunch of files, you can define your routes in a single file. We generally don't recommend this since it's a good idea to code split your app along your routes, but its a neat trick. - -```tsx - - - +```bash +pnpm run clean:all ``` -For consistency between the SSR and client-side rendering modes, we needed to take more control of `root.tsx` specifically, we couldn't just take `` and `` tags and allow them to be part of the component tree since we can't client-side render the whole document. +Then reinstall dependencies and rebuild. -We only really get to take over `document.body`. We needed to ship with special `Html`, `Head`, and `Body` components that you use in `root.tsx` instead of the lower-case counterparts. These document flow components know what to do whether you are in SSR mode on or off. +## Running Tests -- We can avoid you having to include `Meta` and `Links` from `solid-start/root` in your `head` since we do it by default. -- We will always use the title-case variants of the tags used in `head` (eg. `Link` > `link`, `Style` > `style`, `Meta` > `meta`) for consistency throughout the app. -- `solid-meta` is renamed to `@solidjs/meta`. -- `solid-app-router` is renamed to `@solidjs/router`. -- `solid-start` exports all the components meant to be used in your app and these components work on the client and server. Sometimes they are the same on both, and other times they coordinate between the two. +End-to-end tests are located in `apps/tests` projects. For manual testing and development use the `apps/fixtures` apps, and finally, integration and unit tests live inside their respective packages. -Now, our `root.tsx` even more closely replicates how you would be writing your `index.html`. And this was intentionally done so that we could enable an SPA mode for you that used the same code as the SSR mode without changing anything. +1. Install the Chromium for Playwright binary (required only once) -How do we do this? At build time for SPA mode, we quickly run the vite server and make a request for your app's index. We tell our `Body` component not to render anything. + ```bash + pnpm --filter tests exec playwright install chromium + ``` -So, the `index.html` we get is the one you would have written. We then use that `index.html` as your entrypoint. You can still write your own `index.html` if you don't want to use this functionality. +2. For unit tests that check build artifacts, build the test app first -
+ ```bash + pnpm --filter tests run build + ``` -
-

createServerResource -> createServerData$

+3. Run unit tests (puts vitest in watch mode) -Renamed `createServerResource` to `createServerData$`, and `createRouteResource` to `createRouteData`. + ```bash + pnpm --filter tests run unit + ``` -```diff -export function routeData() { -- return createServerResource(async (_, { request }) => { -+ return createServerData$(async (_, { request }) => { - const user = await getUser(request); + - CI mode (run once): `pnpm --filter tests run unit:ci` + - UI mode: `pnpm --filter tests run unit:ui` - if (!user) { - throw redirect("/login"); - } +4. Run E2E tests - return user; - }); -} -``` + ```bash + pnpm --filter tests run e2e + ``` -#### Why? + - UI mode: `pnpm --filter tests run e2e:ui` -We renamed `createServerResource` to `createServerData$` because we were not using the `createResource` signature. That was confusing so we needed to indicate the function was compiled. We just return one single signal from `createServerData$` instead of a tuple like `createResource` does. And we have moved the source into the options as `key`. +5. Clean test artifacts + ```bash + pnpm run clean:test + ``` -
+## Development -
-

createServerAction$, createServerMultiAction$

+1. Make your changes in the relevant package (e.g. `packages/start`) -```diff -- const logoutAction = createServerAction(() => logout(server.request)); -+ const [logginOut, logOut] = createServerAction$((_, { request }) => logout(request)); -``` +2. Rebuild affected packages -#### Why? + ```bash + pnpm run packages:build + ``` -We pass in a `ServerFunctionEvent` which has a `request` field as the second argument to server actions. You can use this to access to the HTTP Request sent for your action and get the headers from it for things like auth. + For a full rebuild: `pnpm run build:all` -We now return a tuple where the first argument is the current submission, and the second is the submit function it also has a progressive enhanceable form attached to it `logout.Form`. +3. Test your changes -
- -
-

๐Ÿ†• HttpStatusCode, HttpHeader

- -```tsx -export default function NotFound() { - return ( -
- - -
- ); -} -``` + - For fixtures, pick the name of the fixture and run the `dev` with workspace filtering. + ```bash + pnpm --filter fixture-basic dev + ``` + - For the landing page (from the root directory) + ```bash + pnpm run lp:dev + ``` -
+4. Clean builds if needed + ```bash + pnpm run packages:clean # Cleans packages' node_modules and dist folders + pnpm run lp:clean # Cleans the landing page + pnpm run clean:root # Cleans root-level caches + ``` -### Credits +--- -All credit for the work on Forms and Sessions goes to the @remix-run team, MIT License, Copyright 2021 Remix Software Inc. +If you have read all the way here, you're already a champ! ๐Ÿ† +Thank you. diff --git a/apps/fixtures/bare/README.md b/apps/fixtures/bare/README.md new file mode 100644 index 000000000..128403d02 --- /dev/null +++ b/apps/fixtures/bare/README.md @@ -0,0 +1,30 @@ +# SolidStart + +Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com); + +## Creating a project + +```bash +# create a new project in the current directory +npm init solid@latest + +# create a new project in my-app +npm init solid@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +Solid apps are built with _presets_, which optimise your project for deployment to different environments. + +By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`. diff --git a/apps/fixtures/bare/package.json b/apps/fixtures/bare/package.json new file mode 100644 index 000000000..f981ebb61 --- /dev/null +++ b/apps/fixtures/bare/package.json @@ -0,0 +1,17 @@ +{ + "name": "fixture-bare", + "type": "module", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build" + }, + "dependencies": { + "@solidjs/start": "workspace:*", + "solid-js": "^1.9.11", + "vite": "7.3.1" + }, + "engines": { + "node": ">=22" + } +} diff --git a/examples/bare/public/favicon.ico b/apps/fixtures/bare/public/favicon.ico similarity index 100% rename from examples/bare/public/favicon.ico rename to apps/fixtures/bare/public/favicon.ico diff --git a/apps/fixtures/bare/src/app.css b/apps/fixtures/bare/src/app.css new file mode 100644 index 000000000..a4d2e55c4 --- /dev/null +++ b/apps/fixtures/bare/src/app.css @@ -0,0 +1,61 @@ +body { + font-family: Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; +} + +a { + margin-right: 1rem; +} + +main { + text-align: center; + padding: 1em; + margin: 0 auto; +} + +h1 { + color: #335d92; + text-transform: uppercase; + font-size: 4rem; + font-weight: 100; + line-height: 1.1; + margin: 4rem auto; + max-width: 14rem; +} + +p { + max-width: 14rem; + margin: 2rem auto; + line-height: 1.35; +} + +@media (min-width: 480px) { + h1 { + max-width: none; + } + + p { + max-width: none; + } +} + +.increment { + font-family: inherit; + font-size: inherit; + padding: 1em 2em; + color: #335d92; + background-color: rgba(68, 107, 158, 0.1); + border-radius: 2em; + border: 2px solid rgba(68, 107, 158, 0); + outline: none; + width: 200px; + font-variant-numeric: tabular-nums; + cursor: pointer; +} + +.increment:focus { + border: 2px solid #335d92; +} + +.increment:active { + background-color: rgba(68, 107, 158, 0.2); +} diff --git a/apps/fixtures/bare/src/app.tsx b/apps/fixtures/bare/src/app.tsx new file mode 100644 index 000000000..bf5aa6acd --- /dev/null +++ b/apps/fixtures/bare/src/app.tsx @@ -0,0 +1,22 @@ +import { createSignal } from "solid-js"; +import "./app.css"; + +export default function App() { + const [count, setCount] = createSignal(0); + + return ( +
+

Hello world!

+ +

+ Visit{" "} + + start.solidjs.com + {" "} + to learn how to build SolidStart apps. +

+
+ ); +} diff --git a/apps/fixtures/bare/src/entry-client.tsx b/apps/fixtures/bare/src/entry-client.tsx new file mode 100644 index 000000000..0ca4e3c30 --- /dev/null +++ b/apps/fixtures/bare/src/entry-client.tsx @@ -0,0 +1,4 @@ +// @refresh reload +import { mount, StartClient } from "@solidjs/start/client"; + +mount(() => , document.getElementById("app")!); diff --git a/apps/fixtures/bare/src/entry-server.tsx b/apps/fixtures/bare/src/entry-server.tsx new file mode 100644 index 000000000..401eff83f --- /dev/null +++ b/apps/fixtures/bare/src/entry-server.tsx @@ -0,0 +1,21 @@ +// @refresh reload +import { createHandler, StartServer } from "@solidjs/start/server"; + +export default createHandler(() => ( + ( + + + + + + {assets} + + +
{children}
+ {scripts} + + + )} + /> +)); diff --git a/apps/fixtures/bare/tsconfig.json b/apps/fixtures/bare/tsconfig.json new file mode 100644 index 000000000..411ce3ba8 --- /dev/null +++ b/apps/fixtures/bare/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + "allowJs": true, + "strict": true, + "noEmit": true, + "isolatedModules": true, + "types": ["@solidjs/start/env"], + "paths": { + "~/*": ["./src/*"], + }, + }, +} diff --git a/apps/fixtures/bare/vite.config.ts b/apps/fixtures/bare/vite.config.ts new file mode 100644 index 000000000..27a23708d --- /dev/null +++ b/apps/fixtures/bare/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import { solidStart } from "../../../packages/start/src/config"; +import { nitroV2Plugin } from "../../../packages/start-nitro-v2-vite-plugin/src"; + +export default defineConfig({ + plugins: [solidStart(), nitroV2Plugin()], +}); diff --git a/apps/fixtures/basic/README.md b/apps/fixtures/basic/README.md new file mode 100644 index 000000000..128403d02 --- /dev/null +++ b/apps/fixtures/basic/README.md @@ -0,0 +1,30 @@ +# SolidStart + +Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com); + +## Creating a project + +```bash +# create a new project in the current directory +npm init solid@latest + +# create a new project in my-app +npm init solid@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +Solid apps are built with _presets_, which optimise your project for deployment to different environments. + +By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`. diff --git a/apps/fixtures/basic/package.json b/apps/fixtures/basic/package.json new file mode 100644 index 000000000..a20fca86f --- /dev/null +++ b/apps/fixtures/basic/package.json @@ -0,0 +1,19 @@ +{ + "name": "fixture-basic", + "type": "module", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build" + }, + "dependencies": { + "@solidjs/meta": "^0.29.4", + "@solidjs/router": "^0.15.4", + "@solidjs/start": "workspace:*", + "solid-js": "^1.9.11", + "vite": "7.3.1" + }, + "engines": { + "node": ">=22" + } +} diff --git a/examples/hackernews/public/favicon.ico b/apps/fixtures/basic/public/favicon.ico similarity index 100% rename from examples/hackernews/public/favicon.ico rename to apps/fixtures/basic/public/favicon.ico diff --git a/examples/with-mdx/src/root.css b/apps/fixtures/basic/src/app.css similarity index 100% rename from examples/with-mdx/src/root.css rename to apps/fixtures/basic/src/app.css diff --git a/apps/fixtures/basic/src/app.tsx b/apps/fixtures/basic/src/app.tsx new file mode 100644 index 000000000..d1359c8d8 --- /dev/null +++ b/apps/fixtures/basic/src/app.tsx @@ -0,0 +1,22 @@ +import { MetaProvider, Title } from "@solidjs/meta"; +import { Router } from "@solidjs/router"; +import { FileRoutes } from "@solidjs/start/router"; +import { Suspense } from "solid-js"; +import "./app.css"; + +export default function App() { + return ( + ( + + SolidStart - Basic + Index + About + {props.children} + + )} + > + + + ); +} diff --git a/apps/fixtures/basic/src/components/Counter.css b/apps/fixtures/basic/src/components/Counter.css new file mode 100644 index 000000000..220e17946 --- /dev/null +++ b/apps/fixtures/basic/src/components/Counter.css @@ -0,0 +1,21 @@ +.increment { + font-family: inherit; + font-size: inherit; + padding: 1em 2em; + color: #335d92; + background-color: rgba(68, 107, 158, 0.1); + border-radius: 2em; + border: 2px solid rgba(68, 107, 158, 0); + outline: none; + width: 200px; + font-variant-numeric: tabular-nums; + cursor: pointer; +} + +.increment:focus { + border: 2px solid #335d92; +} + +.increment:active { + background-color: rgba(68, 107, 158, 0.2); +} \ No newline at end of file diff --git a/apps/fixtures/basic/src/components/Counter.tsx b/apps/fixtures/basic/src/components/Counter.tsx new file mode 100644 index 000000000..091fc5d0b --- /dev/null +++ b/apps/fixtures/basic/src/components/Counter.tsx @@ -0,0 +1,11 @@ +import { createSignal } from "solid-js"; +import "./Counter.css"; + +export default function Counter() { + const [count, setCount] = createSignal(0); + return ( + + ); +} diff --git a/apps/fixtures/basic/src/entry-client.tsx b/apps/fixtures/basic/src/entry-client.tsx new file mode 100644 index 000000000..0ca4e3c30 --- /dev/null +++ b/apps/fixtures/basic/src/entry-client.tsx @@ -0,0 +1,4 @@ +// @refresh reload +import { mount, StartClient } from "@solidjs/start/client"; + +mount(() => , document.getElementById("app")!); diff --git a/apps/fixtures/basic/src/entry-server.tsx b/apps/fixtures/basic/src/entry-server.tsx new file mode 100644 index 000000000..401eff83f --- /dev/null +++ b/apps/fixtures/basic/src/entry-server.tsx @@ -0,0 +1,21 @@ +// @refresh reload +import { createHandler, StartServer } from "@solidjs/start/server"; + +export default createHandler(() => ( + ( + + + + + + {assets} + + +
{children}
+ {scripts} + + + )} + /> +)); diff --git a/apps/fixtures/basic/src/routes/[...404].tsx b/apps/fixtures/basic/src/routes/[...404].tsx new file mode 100644 index 000000000..4ea71ec7f --- /dev/null +++ b/apps/fixtures/basic/src/routes/[...404].tsx @@ -0,0 +1,19 @@ +import { Title } from "@solidjs/meta"; +import { HttpStatusCode } from "@solidjs/start"; + +export default function NotFound() { + return ( +
+ Not Found + +

Page Not Found

+

+ Visit{" "} + + start.solidjs.com + {" "} + to learn how to build SolidStart apps. +

+
+ ); +} diff --git a/apps/fixtures/basic/src/routes/about.tsx b/apps/fixtures/basic/src/routes/about.tsx new file mode 100644 index 000000000..c1c2dcf5a --- /dev/null +++ b/apps/fixtures/basic/src/routes/about.tsx @@ -0,0 +1,10 @@ +import { Title } from "@solidjs/meta"; + +export default function About() { + return ( +
+ About +

About

+
+ ); +} diff --git a/apps/fixtures/basic/src/routes/index.tsx b/apps/fixtures/basic/src/routes/index.tsx new file mode 100644 index 000000000..5d557d819 --- /dev/null +++ b/apps/fixtures/basic/src/routes/index.tsx @@ -0,0 +1,19 @@ +import { Title } from "@solidjs/meta"; +import Counter from "~/components/Counter"; + +export default function Home() { + return ( +
+ Hello World +

Hello world!

+ +

+ Visit{" "} + + start.solidjs.com + {" "} + to learn how to build SolidStart apps. +

+
+ ); +} diff --git a/apps/fixtures/basic/tsconfig.json b/apps/fixtures/basic/tsconfig.json new file mode 100644 index 000000000..411ce3ba8 --- /dev/null +++ b/apps/fixtures/basic/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + "allowJs": true, + "strict": true, + "noEmit": true, + "isolatedModules": true, + "types": ["@solidjs/start/env"], + "paths": { + "~/*": ["./src/*"], + }, + }, +} diff --git a/apps/fixtures/basic/vite.config.ts b/apps/fixtures/basic/vite.config.ts new file mode 100644 index 000000000..27a23708d --- /dev/null +++ b/apps/fixtures/basic/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import { solidStart } from "../../../packages/start/src/config"; +import { nitroV2Plugin } from "../../../packages/start-nitro-v2-vite-plugin/src"; + +export default defineConfig({ + plugins: [solidStart(), nitroV2Plugin()], +}); diff --git a/apps/fixtures/css/README.md b/apps/fixtures/css/README.md new file mode 100644 index 000000000..128403d02 --- /dev/null +++ b/apps/fixtures/css/README.md @@ -0,0 +1,30 @@ +# SolidStart + +Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com); + +## Creating a project + +```bash +# create a new project in the current directory +npm init solid@latest + +# create a new project in my-app +npm init solid@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +Solid apps are built with _presets_, which optimise your project for deployment to different environments. + +By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`. diff --git a/apps/fixtures/css/package.json b/apps/fixtures/css/package.json new file mode 100644 index 000000000..a7c4cf766 --- /dev/null +++ b/apps/fixtures/css/package.json @@ -0,0 +1,24 @@ +{ + "name": "fixture-css", + "type": "module", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "start": "node .output/server/index.mjs" + }, + "dependencies": { + "@solidjs/meta": "^0.29.4", + "@solidjs/router": "^0.15.4", + "@solidjs/start": "workspace:*", + "solid-js": "^1.9.11", + "vite": "7.3.1" + }, + "engines": { + "node": ">=22" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.2.1", + "tailwindcss": "^4.2.1" + } +} diff --git a/examples/todomvc/public/favicon.ico b/apps/fixtures/css/public/favicon.ico similarity index 100% rename from examples/todomvc/public/favicon.ico rename to apps/fixtures/css/public/favicon.ico diff --git a/apps/fixtures/css/src/app.css b/apps/fixtures/css/src/app.css new file mode 100644 index 000000000..7b8888fa1 --- /dev/null +++ b/apps/fixtures/css/src/app.css @@ -0,0 +1,21 @@ +@import "tailwindcss"; + +@theme { + --color-success: var(--color-emerald-700); + --color-error: var(--color-rose-700); + --color-warn: var(--color-orange-500); +} + +@layer base { + body { + @apply bg-gray-800 text-gray-100; + } + + a { + @apply text-sky-400 underline underline-offset-4 hover:no-underline; + } + + h1 { + @apply text-2xl font-bold; + } +} diff --git a/apps/fixtures/css/src/app.tsx b/apps/fixtures/css/src/app.tsx new file mode 100644 index 000000000..32aeff5ec --- /dev/null +++ b/apps/fixtures/css/src/app.tsx @@ -0,0 +1,28 @@ +import { MetaProvider, Title } from "@solidjs/meta"; +import { Router } from "@solidjs/router"; +import { FileRoutes } from "@solidjs/start/router"; +import { Suspense } from "solid-js"; +import "./app.css"; + +export default function App() { + return ( + ( + + SolidStart - CSS Fixture +
+
+ Index + Empty + Unstyled +
+ + {props.children} +
+
+ )} + > + +
+ ); +} diff --git a/apps/fixtures/css/src/components/layout.tsx b/apps/fixtures/css/src/components/layout.tsx new file mode 100644 index 000000000..99763f047 --- /dev/null +++ b/apps/fixtures/css/src/components/layout.tsx @@ -0,0 +1,56 @@ +import { createSignal, FlowProps, onMount } from "solid-js"; +import { getRequestEvent } from "solid-js/web"; + +const Badge = (props: FlowProps) => ( +
{props.children}
+); + +const Layout = (props: FlowProps<{ title: string }>) => { + const [mounted, setMounted] = createSignal(false); + onMount(() => setMounted(true)); + + return ( +
+
+

{props.title}

+ Environment: {import.meta.env.DEV ? "DEV" : "PROD"} + Rendered: {!mounted() ? "Server" : "Server & Client"} +
+ +
+ Agent:{" "} + + {getRequestEvent()?.request.headers.get("user-agent") ?? navigator.userAgent} + +
+ +
    +
  • + Enable throttling & disable cache in the network tab to see eventual FOUC's (frames of + unstyled content) +
  • +
  • Click on routes to test client navigation
  • +
+ +
+
+
Component
+
File
+
Integration
+
Lazy
+
Comments
+
+ + {props.children} +
+ +
+
pass
+
fail
+
not supported
+
+
+ ); +}; + +export default Layout; diff --git a/apps/fixtures/css/src/components/lazy.tsx b/apps/fixtures/css/src/components/lazy.tsx new file mode 100644 index 000000000..1a64df9d1 --- /dev/null +++ b/apps/fixtures/css/src/components/lazy.tsx @@ -0,0 +1,7 @@ +import "../styles/lazy.css"; + +const Lazy = () => { + return <>; +}; + +export default Lazy; diff --git a/apps/fixtures/css/src/components/lazyGlob.tsx b/apps/fixtures/css/src/components/lazyGlob.tsx new file mode 100644 index 000000000..0256e799e --- /dev/null +++ b/apps/fixtures/css/src/components/lazyGlob.tsx @@ -0,0 +1,7 @@ +import "../styles/lazyGlob.css"; + +const Lazy = () => { + return <>; +}; + +export default Lazy; diff --git a/apps/fixtures/css/src/components/lazyLink.tsx b/apps/fixtures/css/src/components/lazyLink.tsx new file mode 100644 index 000000000..5d352d41b --- /dev/null +++ b/apps/fixtures/css/src/components/lazyLink.tsx @@ -0,0 +1,5 @@ +import url from "../styles/lazyLink.css?url"; + +const Lazy = () => ; + +export default Lazy; diff --git a/apps/fixtures/css/src/components/lazyLinkTmp.tsx b/apps/fixtures/css/src/components/lazyLinkTmp.tsx new file mode 100644 index 000000000..6061f995b --- /dev/null +++ b/apps/fixtures/css/src/components/lazyLinkTmp.tsx @@ -0,0 +1,5 @@ +import url from "../styles/lazyLinkTmp.css?url"; + +const Lazy = () => ; + +export default Lazy; diff --git a/apps/fixtures/css/src/components/sharedChunk/lazy1.tsx b/apps/fixtures/css/src/components/sharedChunk/lazy1.tsx new file mode 100644 index 000000000..484d65e92 --- /dev/null +++ b/apps/fixtures/css/src/components/sharedChunk/lazy1.tsx @@ -0,0 +1,5 @@ +import "../../styles/sharedChunk.css"; + +export default () => { + return <>; +}; diff --git a/apps/fixtures/css/src/components/sharedChunk/lazy2.tsx b/apps/fixtures/css/src/components/sharedChunk/lazy2.tsx new file mode 100644 index 000000000..42083cc07 --- /dev/null +++ b/apps/fixtures/css/src/components/sharedChunk/lazy2.tsx @@ -0,0 +1,3 @@ +export default () => { + return <>; +}; diff --git a/apps/fixtures/css/src/components/test.tsx b/apps/fixtures/css/src/components/test.tsx new file mode 100644 index 000000000..21defb028 --- /dev/null +++ b/apps/fixtures/css/src/components/test.tsx @@ -0,0 +1,126 @@ +import { JSX } from "solid-js"; + +const clsx = (...args: (string | false | undefined)[]) => args.filter(Boolean).join(" "); + +const integrations = { + import: "import", + module: "import module", + url: "?url without render", + link: "?url + ", +}; +const Test = (props: { + invert?: boolean; + class?: string; + component: string; + file: string; + integration?: keyof typeof integrations; + lazy?: boolean; + noSupport?: boolean; + comment?: JSX.Element; +}) => ( +
+
{props.component}
+
{props.file}
+
{integrations[props.integration ?? "import"]}
+
{props.lazy ? <>✓ : null}
+
{props.comment}
+
+); + +export const CommonTests = (props: { routeModuleClass?: string }) => ( + <> + + + + + + + + + + + + + + Tests fallbacks, only mounted while loading. +
+ Red while mounted. + + } + /> + + Tests if CSS from shared chunks is server rendered properly. Rollup occasionally combines + modules into such shared chunks. + + } + /> + +); + +export default Test; diff --git a/apps/fixtures/css/src/entry-client.tsx b/apps/fixtures/css/src/entry-client.tsx new file mode 100644 index 000000000..b9fc52a4e --- /dev/null +++ b/apps/fixtures/css/src/entry-client.tsx @@ -0,0 +1,5 @@ +// @refresh reload +import { mount, StartClient } from "@solidjs/start/client"; +import "./styles/entryClient.css"; + +mount(() => , document.getElementById("app")!); diff --git a/apps/fixtures/css/src/entry-server.tsx b/apps/fixtures/css/src/entry-server.tsx new file mode 100644 index 000000000..47822cea1 --- /dev/null +++ b/apps/fixtures/css/src/entry-server.tsx @@ -0,0 +1,24 @@ +// @refresh reload +import { createHandler, StartServer } from "@solidjs/start/server"; +import "./styles/entryServer.css"; +import url from "./styles/entryServerUrl.css?url"; + +export default createHandler(() => ( + ( + + + + + + + {assets} + + +
{children}
+ {scripts} + + + )} + /> +)); diff --git a/apps/fixtures/css/src/routes/[...404].tsx b/apps/fixtures/css/src/routes/[...404].tsx new file mode 100644 index 000000000..4ea71ec7f --- /dev/null +++ b/apps/fixtures/css/src/routes/[...404].tsx @@ -0,0 +1,19 @@ +import { Title } from "@solidjs/meta"; +import { HttpStatusCode } from "@solidjs/start"; + +export default function NotFound() { + return ( +
+ Not Found + +

Page Not Found

+

+ Visit{" "} + + start.solidjs.com + {" "} + to learn how to build SolidStart apps. +

+
+ ); +} diff --git a/apps/fixtures/css/src/routes/empty.tsx b/apps/fixtures/css/src/routes/empty.tsx new file mode 100644 index 000000000..65eff5795 --- /dev/null +++ b/apps/fixtures/css/src/routes/empty.tsx @@ -0,0 +1,10 @@ +import { Title } from "@solidjs/meta"; + +export default function Empty() { + return ( +
+ Empty +

Empty

+
+ ); +} diff --git a/apps/fixtures/css/src/routes/index.tsx b/apps/fixtures/css/src/routes/index.tsx new file mode 100644 index 000000000..3b4fa0f6e --- /dev/null +++ b/apps/fixtures/css/src/routes/index.tsx @@ -0,0 +1,51 @@ +import { createAsync, query } from "@solidjs/router"; +import { lazy, Show } from "solid-js"; +import "virtual:virtualModule.css"; +import Layout from "../components/layout"; +import { CommonTests } from "../components/test"; +import notRenderedInlineCSS from "../styles/notRendered.css?url"; +import "../styles/route.css"; +import classes from "../styles/route.module.css"; +import renderedInlineCSS from "../styles/url.css?url"; + +const Lazy = lazy(() => import("../components/lazy")); +const LazyLink = lazy(() => import("../components/lazyLink")); +const LazyLinkTmp = lazy(() => import("../components/lazyLinkTmp")); + +const entries = import.meta.glob("../components/lazyG*.tsx"); +const LazyGlob = lazy(Object.values(entries)[0] as any); + +const SharedChunk = lazy(() => import("../components/sharedChunk/lazy1")); +// Do not remove this. +// Rollup only creates a shared chunk if there are atleast two modules. +lazy(() => import("../components/sharedChunk/lazy2")); + +const getData = query(async () => { + "use server"; + await new Promise(res => setTimeout(res, 1000)); + return "CSS Tests"; +}, "data"); + +export default function Home() { + const data = createAsync(() => getData(), { deferStream: true }); + + return ( +
+ + + + + + + + + + + + + + + +
+ ); +} diff --git a/apps/fixtures/css/src/routes/unstyled.tsx b/apps/fixtures/css/src/routes/unstyled.tsx new file mode 100644 index 000000000..f9b22315f --- /dev/null +++ b/apps/fixtures/css/src/routes/unstyled.tsx @@ -0,0 +1,14 @@ +import { Title } from "@solidjs/meta"; +import Layout from "../components/layout"; +import { CommonTests } from "../components/test"; + +export default function Others() { + return ( +
+ Unstyled + + + +
+ ); +} diff --git a/apps/fixtures/css/src/styles/entryClient.css b/apps/fixtures/css/src/styles/entryClient.css new file mode 100644 index 000000000..84dafa95c --- /dev/null +++ b/apps/fixtures/css/src/styles/entryClient.css @@ -0,0 +1,3 @@ +.entryClient { + background-color: var(--color-success); +} diff --git a/apps/fixtures/css/src/styles/entryServer.css b/apps/fixtures/css/src/styles/entryServer.css new file mode 100644 index 000000000..aac9295a0 --- /dev/null +++ b/apps/fixtures/css/src/styles/entryServer.css @@ -0,0 +1,3 @@ +.entryServer { + background-color: var(--color-success); +} diff --git a/apps/fixtures/css/src/styles/entryServerUrl.css b/apps/fixtures/css/src/styles/entryServerUrl.css new file mode 100644 index 000000000..ce4d8b91c --- /dev/null +++ b/apps/fixtures/css/src/styles/entryServerUrl.css @@ -0,0 +1,3 @@ +.entryServerUrl { + background-color: var(--color-success); +} diff --git a/apps/fixtures/css/src/styles/lazy.css b/apps/fixtures/css/src/styles/lazy.css new file mode 100644 index 000000000..fdc1d5a60 --- /dev/null +++ b/apps/fixtures/css/src/styles/lazy.css @@ -0,0 +1,3 @@ +.lazy { + background-color: var(--color-success); +} diff --git a/apps/fixtures/css/src/styles/lazyGlob.css b/apps/fixtures/css/src/styles/lazyGlob.css new file mode 100644 index 000000000..4c7b92f51 --- /dev/null +++ b/apps/fixtures/css/src/styles/lazyGlob.css @@ -0,0 +1,3 @@ +.lazyGlob { + background-color: var(--color-success); +} diff --git a/apps/fixtures/css/src/styles/lazyLink.css b/apps/fixtures/css/src/styles/lazyLink.css new file mode 100644 index 000000000..50c6d1663 --- /dev/null +++ b/apps/fixtures/css/src/styles/lazyLink.css @@ -0,0 +1,3 @@ +.lazyLink { + background-color: var(--color-success); +} diff --git a/apps/fixtures/css/src/styles/lazyLinkTmp.css b/apps/fixtures/css/src/styles/lazyLinkTmp.css new file mode 100644 index 000000000..3523d74df --- /dev/null +++ b/apps/fixtures/css/src/styles/lazyLinkTmp.css @@ -0,0 +1,3 @@ +.lazyLinkTmp { + background-color: var(--color-error); +} diff --git a/apps/fixtures/css/src/styles/notRendered.css b/apps/fixtures/css/src/styles/notRendered.css new file mode 100644 index 000000000..bf07490f8 --- /dev/null +++ b/apps/fixtures/css/src/styles/notRendered.css @@ -0,0 +1,3 @@ +.notRendered { + background-color: var(--color-error); +} diff --git a/apps/fixtures/css/src/styles/route.css b/apps/fixtures/css/src/styles/route.css new file mode 100644 index 000000000..1cddfd725 --- /dev/null +++ b/apps/fixtures/css/src/styles/route.css @@ -0,0 +1,3 @@ +.route { + background-color: var(--color-success); +} diff --git a/apps/fixtures/css/src/styles/route.module.css b/apps/fixtures/css/src/styles/route.module.css new file mode 100644 index 000000000..1cddfd725 --- /dev/null +++ b/apps/fixtures/css/src/styles/route.module.css @@ -0,0 +1,3 @@ +.route { + background-color: var(--color-success); +} diff --git a/apps/fixtures/css/src/styles/sharedChunk.css b/apps/fixtures/css/src/styles/sharedChunk.css new file mode 100644 index 000000000..bdc50263a --- /dev/null +++ b/apps/fixtures/css/src/styles/sharedChunk.css @@ -0,0 +1,3 @@ +.sharedChunk { + background-color: var(--color-success); +} diff --git a/apps/fixtures/css/src/styles/url.css b/apps/fixtures/css/src/styles/url.css new file mode 100644 index 000000000..a587a91d2 --- /dev/null +++ b/apps/fixtures/css/src/styles/url.css @@ -0,0 +1,3 @@ +.url { + background-color: var(--color-success); +} diff --git a/apps/fixtures/css/src/virtualCssPlugin.ts b/apps/fixtures/css/src/virtualCssPlugin.ts new file mode 100644 index 000000000..897dc872d --- /dev/null +++ b/apps/fixtures/css/src/virtualCssPlugin.ts @@ -0,0 +1,18 @@ +import { Plugin } from "vite"; + +const id = "virtual:virtualModule.css"; +const resolvedId = "\0" + id; + +const virtualCSS = () => + ({ + name: "css-fixture-virtual-css", + resolveId(source) { + if (source === id) return resolvedId; + }, + load(id) { + if (id.startsWith(resolvedId)) + return `.virtualCss { background-color: var(--color-success); }`; + }, + }) satisfies Plugin; + +export default virtualCSS; diff --git a/apps/fixtures/css/tsconfig.json b/apps/fixtures/css/tsconfig.json new file mode 100644 index 000000000..e4bb71b1e --- /dev/null +++ b/apps/fixtures/css/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + "allowJs": true, + "strict": true, + "noEmit": true, + "isolatedModules": true, + "paths": { + "~/*": ["./src/*"], + }, + "types": ["@solidjs/start/env"], + }, +} diff --git a/apps/fixtures/css/vite.config.ts b/apps/fixtures/css/vite.config.ts new file mode 100644 index 000000000..976e4a84d --- /dev/null +++ b/apps/fixtures/css/vite.config.ts @@ -0,0 +1,27 @@ +import tailwindcss from "@tailwindcss/vite"; +import { defineConfig } from "vite"; +import { nitroV2Plugin } from "../../../packages/start-nitro-v2-vite-plugin/src"; +import { solidStart } from "../../../packages/start/src/config"; +import virtualCSS from "./src/virtualCssPlugin"; + +export default defineConfig({ + plugins: [virtualCSS(), solidStart(), nitroV2Plugin(), tailwindcss()], + build: { + rollupOptions: { + output: { + /** + * Creates a shared chunk with two components. Needed for the "SharedChunk" test! + * The vite manifest behaves differently for such shared chunks. + * More info: packages/start/src/config/lazy.ts + * + * TODO: When switching to Rolldown, migrate this to advancedChunks + * https://vite.dev/guide/rolldown.html#manualchunks-to-advancedchunks + */ + manualChunks(id) { + if (!id.includes("src/components/sharedChunk")) return; + return "shared"; + }, + }, + }, + }, +}); diff --git a/apps/fixtures/experiments/README.md b/apps/fixtures/experiments/README.md new file mode 100644 index 000000000..128403d02 --- /dev/null +++ b/apps/fixtures/experiments/README.md @@ -0,0 +1,30 @@ +# SolidStart + +Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com); + +## Creating a project + +```bash +# create a new project in the current directory +npm init solid@latest + +# create a new project in my-app +npm init solid@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +Solid apps are built with _presets_, which optimise your project for deployment to different environments. + +By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`. diff --git a/apps/fixtures/experiments/package.json b/apps/fixtures/experiments/package.json new file mode 100644 index 000000000..32f10ed3e --- /dev/null +++ b/apps/fixtures/experiments/package.json @@ -0,0 +1,19 @@ +{ + "name": "fixture-experiments", + "type": "module", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build" + }, + "dependencies": { + "@solidjs/meta": "^0.29.4", + "@solidjs/router": "^0.15.4", + "@solidjs/start": "workspace:*", + "solid-js": "^1.9.11", + "vite": "7.3.1" + }, + "engines": { + "node": ">=22" + } +} diff --git a/examples/with-auth/public/favicon.ico b/apps/fixtures/experiments/public/favicon.ico similarity index 100% rename from examples/with-auth/public/favicon.ico rename to apps/fixtures/experiments/public/favicon.ico diff --git a/apps/fixtures/experiments/src/app.css b/apps/fixtures/experiments/src/app.css new file mode 100644 index 000000000..8596998a4 --- /dev/null +++ b/apps/fixtures/experiments/src/app.css @@ -0,0 +1,39 @@ +body { + font-family: Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; +} + +a { + margin-right: 1rem; +} + +main { + text-align: center; + padding: 1em; + margin: 0 auto; +} + +h1 { + color: #335d92; + text-transform: uppercase; + font-size: 4rem; + font-weight: 100; + line-height: 1.1; + margin: 4rem auto; + max-width: 14rem; +} + +p { + max-width: 14rem; + margin: 2rem auto; + line-height: 1.35; +} + +@media (min-width: 480px) { + h1 { + max-width: none; + } + + p { + max-width: none; + } +} diff --git a/apps/fixtures/experiments/src/app.tsx b/apps/fixtures/experiments/src/app.tsx new file mode 100644 index 000000000..912b2232a --- /dev/null +++ b/apps/fixtures/experiments/src/app.tsx @@ -0,0 +1,25 @@ +import { MetaProvider, Title } from "@solidjs/meta"; +import { Router } from "@solidjs/router"; +import { FileRoutes } from "@solidjs/start/router"; +import { Suspense } from "solid-js"; +import "./app.css"; +import Provider from "./components/Provider"; + +export default function App() { + return ( + ( + + + SolidStart - Bare + Index + About + {props.children} + + + )} + > + + + ); +} diff --git a/apps/fixtures/experiments/src/components/BreaksOnServer.tsx b/apps/fixtures/experiments/src/components/BreaksOnServer.tsx new file mode 100644 index 000000000..f6b161610 --- /dev/null +++ b/apps/fixtures/experiments/src/components/BreaksOnServer.tsx @@ -0,0 +1,6 @@ +// trouble maker +const location = window.document.location; + +export default function BreaksOnServer() { + return
Breaks on server {location.href}
; +} diff --git a/apps/fixtures/experiments/src/components/Counter.css b/apps/fixtures/experiments/src/components/Counter.css new file mode 100644 index 000000000..220e17946 --- /dev/null +++ b/apps/fixtures/experiments/src/components/Counter.css @@ -0,0 +1,21 @@ +.increment { + font-family: inherit; + font-size: inherit; + padding: 1em 2em; + color: #335d92; + background-color: rgba(68, 107, 158, 0.1); + border-radius: 2em; + border: 2px solid rgba(68, 107, 158, 0); + outline: none; + width: 200px; + font-variant-numeric: tabular-nums; + cursor: pointer; +} + +.increment:focus { + border: 2px solid #335d92; +} + +.increment:active { + background-color: rgba(68, 107, 158, 0.2); +} \ No newline at end of file diff --git a/apps/fixtures/experiments/src/components/Counter.tsx b/apps/fixtures/experiments/src/components/Counter.tsx new file mode 100644 index 000000000..efc77cf31 --- /dev/null +++ b/apps/fixtures/experiments/src/components/Counter.tsx @@ -0,0 +1,14 @@ +"use client"; + +import { useContext } from "solid-js"; +import "./Counter.css"; +import counterContext from "./counterContext"; + +export default function Counter() { + const [count, setCount] = useContext(counterContext); + return ( + + ); +} diff --git a/apps/fixtures/experiments/src/components/Provider.tsx b/apps/fixtures/experiments/src/components/Provider.tsx new file mode 100644 index 000000000..581a6ea67 --- /dev/null +++ b/apps/fixtures/experiments/src/components/Provider.tsx @@ -0,0 +1,11 @@ +"use client"; +import { createSignal } from "solid-js"; +import counterContext from "./counterContext"; + +export default function Provider(props) { + return ( + + {props.children} + + ); +} diff --git a/apps/fixtures/experiments/src/components/counterContext.tsx b/apps/fixtures/experiments/src/components/counterContext.tsx new file mode 100644 index 000000000..871ffc9bb --- /dev/null +++ b/apps/fixtures/experiments/src/components/counterContext.tsx @@ -0,0 +1,4 @@ +"use client"; +import { createContext, createSignal } from "solid-js"; + +export default createContext(createSignal(0)); diff --git a/apps/fixtures/experiments/src/entry-client.tsx b/apps/fixtures/experiments/src/entry-client.tsx new file mode 100644 index 000000000..0ca4e3c30 --- /dev/null +++ b/apps/fixtures/experiments/src/entry-client.tsx @@ -0,0 +1,4 @@ +// @refresh reload +import { mount, StartClient } from "@solidjs/start/client"; + +mount(() => , document.getElementById("app")!); diff --git a/apps/fixtures/experiments/src/entry-server.tsx b/apps/fixtures/experiments/src/entry-server.tsx new file mode 100644 index 000000000..3cc2ec0c5 --- /dev/null +++ b/apps/fixtures/experiments/src/entry-server.tsx @@ -0,0 +1,28 @@ +// @refresh reload +import { StartServer, createHandler } from "@solidjs/start/server"; + +declare module "@solidjs/start/server" { + interface RequestEventLocals { + n: number; + s: string; + } +} + +export default createHandler(() => ( + ( + + + + + + {assets} + + +
{children}
+ {scripts} + + + )} + /> +)); diff --git a/apps/fixtures/experiments/src/middleware.ts b/apps/fixtures/experiments/src/middleware.ts new file mode 100644 index 000000000..4b54dfb5e --- /dev/null +++ b/apps/fixtures/experiments/src/middleware.ts @@ -0,0 +1,20 @@ +import { getRequestURL } from "@solidjs/start/http"; +import { createMiddleware } from "@solidjs/start/middleware"; + +export default createMiddleware({ + onRequest: [ + event => { + event.locals.foo = "bar"; + console.log("REQUEST", event.request.url); + console.log( + "SEARCH PARAM KEYS FROM ASYNC CONTEXT", + Array.from(getRequestURL().searchParams.keys()), + ); + }, + ], + onBeforeResponse: [ + (event, { body }) => { + console.log("BEFORE RESPONSE", body); + }, + ], +}); diff --git a/apps/fixtures/experiments/src/routes/(group).tsx b/apps/fixtures/experiments/src/routes/(group).tsx new file mode 100644 index 000000000..f8b17d8fd --- /dev/null +++ b/apps/fixtures/experiments/src/routes/(group).tsx @@ -0,0 +1,10 @@ +import { RouteSectionProps } from "@solidjs/router"; + +export default function (props: RouteSectionProps) { + return ( + <> +

Group

+ {props.children} + + ); +} diff --git a/apps/fixtures/experiments/src/routes/(group)/endpoint.ts b/apps/fixtures/experiments/src/routes/(group)/endpoint.ts new file mode 100644 index 000000000..ace4e0247 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/(group)/endpoint.ts @@ -0,0 +1,3 @@ +export function GET() { + return new Response("Hello World"); +} diff --git a/apps/fixtures/experiments/src/routes/(group)/other.tsx b/apps/fixtures/experiments/src/routes/(group)/other.tsx new file mode 100644 index 000000000..64c3cec02 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/(group)/other.tsx @@ -0,0 +1,3 @@ +export default function () { + return
OTHER
; +} diff --git a/apps/fixtures/experiments/src/routes/(group2).tsx b/apps/fixtures/experiments/src/routes/(group2).tsx new file mode 100644 index 000000000..b6f213fb2 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/(group2).tsx @@ -0,0 +1,10 @@ +import { RouteSectionProps } from "@solidjs/router"; + +export default function (props: RouteSectionProps) { + return ( + <> +

Group 2

+ {props.children} + + ); +} diff --git a/apps/fixtures/experiments/src/routes/(group2)/something.tsx b/apps/fixtures/experiments/src/routes/(group2)/something.tsx new file mode 100644 index 000000000..0cab8149c --- /dev/null +++ b/apps/fixtures/experiments/src/routes/(group2)/something.tsx @@ -0,0 +1,3 @@ +export default function () { + return
SOMETHING
; +} diff --git a/apps/fixtures/experiments/src/routes/[...404].tsx b/apps/fixtures/experiments/src/routes/[...404].tsx new file mode 100644 index 000000000..c2329dac9 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/[...404].tsx @@ -0,0 +1,25 @@ +import { Title } from "@solidjs/meta"; +import { HttpStatusCode } from "@solidjs/start"; +import type { APIEvent } from "@solidjs/start/server"; + +export const GET = (event: APIEvent) => { + if (event.request.headers.get("accept") !== "application/json") return; + return { notFound: "API" }; +}; + +export default function NotFound() { + return ( +
+ Not Found + +

Page Not Found

+

+ Visit{" "} + + start.solidjs.com + {" "} + to learn how to build SolidStart apps. +

+
+ ); +} diff --git a/apps/fixtures/experiments/src/routes/[[option]]/thing.tsx b/apps/fixtures/experiments/src/routes/[[option]]/thing.tsx new file mode 100644 index 000000000..4135b83e8 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/[[option]]/thing.tsx @@ -0,0 +1,5 @@ +import type { RouteSectionProps } from "@solidjs/router"; + +export default function (props: RouteSectionProps) { + return
THING: {props.params.option || "NO"}
; +} diff --git a/apps/fixtures/experiments/src/routes/api.ts b/apps/fixtures/experiments/src/routes/api.ts new file mode 100644 index 000000000..d3f8125f8 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/api.ts @@ -0,0 +1,7 @@ +export function GET() { + return "hello world"; +} + +export function DELETE() { + console.log("Deleted"); +} diff --git a/apps/fixtures/experiments/src/routes/api/hello/[name].ts b/apps/fixtures/experiments/src/routes/api/hello/[name].ts new file mode 100644 index 000000000..98a0d9713 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/api/hello/[name].ts @@ -0,0 +1,5 @@ +import type { APIHandler } from "@solidjs/start/server"; + +export const GET: APIHandler = async ({ params }) => { + return `Hello ${params.name}!`; +}; diff --git a/apps/fixtures/experiments/src/routes/index.tsx b/apps/fixtures/experiments/src/routes/index.tsx new file mode 100644 index 000000000..189744fb1 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/index.tsx @@ -0,0 +1,44 @@ +import { Title } from "@solidjs/meta"; +import { json } from "@solidjs/router"; +import { clientOnly, GET } from "@solidjs/start"; +import { getServerFunctionMeta } from "@solidjs/start/server"; +import { getRequestEvent, isServer } from "solid-js/web"; +import Counter from "~/components/Counter"; +const BreaksOnServer = clientOnly(() => import("~/components/BreaksOnServer")); + +const hello = GET(async (name: string) => { + "use server"; + const e = getRequestEvent()!; + const { id } = getServerFunctionMeta()!; + console.log("ID", id, e.locals.foo); + return json( + { hello: new Promise(r => setTimeout(() => r(name), 1000)) }, + { headers: { "cache-control": "max-age=60" } }, + ); +}); + +export default function Home() { + hello("John").then(async v => { + console.log(v); + console.log(await v.hello); + }); + const port = isServer ? new URL(getRequestEvent()!.request.url).port : location.port; + fetch(`http://localhost:${port}${import.meta.env.BASE_URL}/unknown`, { + headers: { Accept: "application/json" }, + }).then(async res => console.log(await res.json())); + return ( +
+ Hello World +

Hello world!

+ + +

+ Visit{" "} + + start.solidjs.com + {" "} + to learn how to build SolidStart apps. +

+
+ ); +} diff --git a/apps/fixtures/experiments/src/routes/test(named)/[name].tsx b/apps/fixtures/experiments/src/routes/test(named)/[name].tsx new file mode 100644 index 000000000..3b703e4b7 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/test(named)/[name].tsx @@ -0,0 +1,10 @@ +import { RouteSectionProps } from "@solidjs/router"; + +export default function (props: RouteSectionProps) { + return ( + <> +

Different Layout

+ {props.children} + + ); +} diff --git a/apps/fixtures/experiments/src/routes/test(named)/[name]/home.tsx b/apps/fixtures/experiments/src/routes/test(named)/[name]/home.tsx new file mode 100644 index 000000000..ed60ca55d --- /dev/null +++ b/apps/fixtures/experiments/src/routes/test(named)/[name]/home.tsx @@ -0,0 +1,3 @@ +export default function () { + return
DIFFERENT CONTENT
; +} diff --git a/apps/fixtures/experiments/src/routes/test(nolayout)/nolayout.tsx b/apps/fixtures/experiments/src/routes/test(nolayout)/nolayout.tsx new file mode 100644 index 000000000..0deb14bf7 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/test(nolayout)/nolayout.tsx @@ -0,0 +1,3 @@ +export default function () { + return

Without Layout

; +} diff --git a/apps/fixtures/experiments/src/routes/test.tsx b/apps/fixtures/experiments/src/routes/test.tsx new file mode 100644 index 000000000..c342feaf9 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/test.tsx @@ -0,0 +1,10 @@ +import { RouteSectionProps } from "@solidjs/router"; + +export default function (props: RouteSectionProps) { + return ( + <> +

Layout

+ {props.children} + + ); +} diff --git a/apps/fixtures/experiments/src/routes/test/(hi).tsx b/apps/fixtures/experiments/src/routes/test/(hi).tsx new file mode 100644 index 000000000..5e6a5aa68 --- /dev/null +++ b/apps/fixtures/experiments/src/routes/test/(hi).tsx @@ -0,0 +1,3 @@ +export default function () { + return
CONTENT
; +} diff --git a/apps/fixtures/experiments/src/routes/test/[name].tsx b/apps/fixtures/experiments/src/routes/test/[name].tsx new file mode 100644 index 000000000..9ea84914d --- /dev/null +++ b/apps/fixtures/experiments/src/routes/test/[name].tsx @@ -0,0 +1,5 @@ +import { RouteSectionProps } from "@solidjs/router"; + +export default function (props: RouteSectionProps) { + return
{props.params.name}
; +} diff --git "a/apps/fixtures/experiments/src/routes/\346\274\242\345\255\227.tsx" "b/apps/fixtures/experiments/src/routes/\346\274\242\345\255\227.tsx" new file mode 100644 index 000000000..c8920b4a5 --- /dev/null +++ "b/apps/fixtures/experiments/src/routes/\346\274\242\345\255\227.tsx" @@ -0,0 +1,3 @@ +export default function () { + return
ๆผขๅญ—
; +} diff --git a/apps/fixtures/experiments/tsconfig.json b/apps/fixtures/experiments/tsconfig.json new file mode 100644 index 000000000..411ce3ba8 --- /dev/null +++ b/apps/fixtures/experiments/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + "allowJs": true, + "strict": true, + "noEmit": true, + "isolatedModules": true, + "types": ["@solidjs/start/env"], + "paths": { + "~/*": ["./src/*"], + }, + }, +} diff --git a/apps/fixtures/experiments/vite.config.ts b/apps/fixtures/experiments/vite.config.ts new file mode 100644 index 000000000..57596416d --- /dev/null +++ b/apps/fixtures/experiments/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import { solidStart } from "../../../packages/start/src/config"; +import { nitroV2Plugin } from "../../../packages/start-nitro-v2-vite-plugin/src"; + +export default defineConfig({ + plugins: [solidStart({ middleware: "./src/middleware.ts" }), nitroV2Plugin()], +}); diff --git a/apps/fixtures/hackernews/README.md b/apps/fixtures/hackernews/README.md new file mode 100644 index 000000000..9b413de8d --- /dev/null +++ b/apps/fixtures/hackernews/README.md @@ -0,0 +1,30 @@ +# SolidStart Hackernews Example + +Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com); + +## Creating a project + +```bash +# create a new project in the current directory +npm init solid@latest + +# create a new project in my-app +npm init solid@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +Solid apps are built with _presets_, which optimise your project for deployment to different environments. + +By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`. diff --git a/apps/fixtures/hackernews/package.json b/apps/fixtures/hackernews/package.json new file mode 100644 index 000000000..cfc38e864 --- /dev/null +++ b/apps/fixtures/hackernews/package.json @@ -0,0 +1,18 @@ +{ + "name": "fixture-hackernews", + "type": "module", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build" + }, + "dependencies": { + "@solidjs/router": "^0.15.4", + "@solidjs/start": "workspace:*", + "solid-js": "^1.9.11", + "vite": "7.3.1" + }, + "engines": { + "node": ">=22" + } +} diff --git a/examples/with-mdx/public/favicon.ico b/apps/fixtures/hackernews/public/favicon.ico similarity index 100% rename from examples/with-mdx/public/favicon.ico rename to apps/fixtures/hackernews/public/favicon.ico diff --git a/examples/hackernews/public/img/android-chrome-192x192.png b/apps/fixtures/hackernews/public/img/android-chrome-192x192.png similarity index 100% rename from examples/hackernews/public/img/android-chrome-192x192.png rename to apps/fixtures/hackernews/public/img/android-chrome-192x192.png diff --git a/examples/hackernews/public/img/android-chrome-512x512.png b/apps/fixtures/hackernews/public/img/android-chrome-512x512.png similarity index 100% rename from examples/hackernews/public/img/android-chrome-512x512.png rename to apps/fixtures/hackernews/public/img/android-chrome-512x512.png diff --git a/examples/hackernews/public/img/apple-touch-icon.png b/apps/fixtures/hackernews/public/img/apple-touch-icon.png similarity index 100% rename from examples/hackernews/public/img/apple-touch-icon.png rename to apps/fixtures/hackernews/public/img/apple-touch-icon.png diff --git a/examples/hackernews/public/img/favicon-16x16.png b/apps/fixtures/hackernews/public/img/favicon-16x16.png similarity index 100% rename from examples/hackernews/public/img/favicon-16x16.png rename to apps/fixtures/hackernews/public/img/favicon-16x16.png diff --git a/examples/hackernews/public/img/favicon-32x32.png b/apps/fixtures/hackernews/public/img/favicon-32x32.png similarity index 100% rename from examples/hackernews/public/img/favicon-32x32.png rename to apps/fixtures/hackernews/public/img/favicon-32x32.png diff --git a/examples/hackernews/public/img/mstile-150x150.png b/apps/fixtures/hackernews/public/img/mstile-150x150.png similarity index 100% rename from examples/hackernews/public/img/mstile-150x150.png rename to apps/fixtures/hackernews/public/img/mstile-150x150.png diff --git a/examples/hackernews/public/manifest.webmanifest b/apps/fixtures/hackernews/public/manifest.webmanifest similarity index 100% rename from examples/hackernews/public/manifest.webmanifest rename to apps/fixtures/hackernews/public/manifest.webmanifest diff --git a/examples/hackernews/public/robots.txt b/apps/fixtures/hackernews/public/robots.txt similarity index 100% rename from examples/hackernews/public/robots.txt rename to apps/fixtures/hackernews/public/robots.txt diff --git a/apps/fixtures/hackernews/public/sw.js b/apps/fixtures/hackernews/public/sw.js new file mode 100644 index 000000000..fcf9d79af --- /dev/null +++ b/apps/fixtures/hackernews/public/sw.js @@ -0,0 +1,14 @@ +self.addEventListener("fetch", e => { + (e.request.url.includes("localhost") || e.request.url.includes("workers")) && + e.respondWith( + caches + .open("solid-hn") + .then(t => + t + .match(e.request) + .then(n => n || fetch(e.request).then(n => (t.put(e.request, n.clone()), n))), + ), + ); +}); + +self.addEventListener("activate", e => e.waitUntil(caches.delete("solid-hn"))); diff --git a/examples/hackernews/src/root.css b/apps/fixtures/hackernews/src/app.css similarity index 100% rename from examples/hackernews/src/root.css rename to apps/fixtures/hackernews/src/app.css diff --git a/apps/fixtures/hackernews/src/app.tsx b/apps/fixtures/hackernews/src/app.tsx new file mode 100644 index 000000000..82e4c0de1 --- /dev/null +++ b/apps/fixtures/hackernews/src/app.tsx @@ -0,0 +1,22 @@ +import { Router } from "@solidjs/router"; +import { FileRoutes } from "@solidjs/start/router"; +import { Suspense } from "solid-js"; +import "./app.css"; +import Nav from "./components/nav"; + +export default function App() { + return ( + ( + <> +