diff --git a/package.json b/package.json
index 41c827772..ded19c23c 100644
--- a/package.json
+++ b/package.json
@@ -21,10 +21,10 @@
"@kobalte/solidbase": "catalog:",
"@solidjs/meta": "^0.29.4",
"@solidjs/router": "^0.16.1",
- "@solidjs/start": "https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080",
+ "@solidjs/start": "2.0.0-rc.1",
"@tailwindcss/vite": "^4.3.0",
"dotenv": "^17.3.1",
- "nitro": "v3.0.260429-beta",
+ "nitro": "^3.0.260610-beta",
"resolve": "1.22.12",
"solid-heroicons": "^3.2.4",
"solid-js": "1.9.12",
@@ -51,7 +51,7 @@
"typescript-eslint": "^8.54.0"
},
"overrides": {
- "@solidjs/start": "https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080"
+ "@solidjs/start": "2.0.0-rc.1"
},
"engines": {
"node": ">=24",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4a7f0eca5..2f6171fe0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -21,7 +21,7 @@ importers:
version: 0.13.11(solid-js@1.9.12)
"@kobalte/solidbase":
specifier: "catalog:"
- version: 0.6.4(@solidjs/start@https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080(crossws@0.4.5(srvx@0.11.15))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(solid-js@1.9.12)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
+ version: 0.6.4(@solidjs/start@2.0.0-rc.1(crossws@0.4.10(srvx@0.11.22))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(solid-js@1.9.12)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
"@solidjs/meta":
specifier: ^0.29.4
version: 0.29.4(solid-js@1.9.12)
@@ -29,8 +29,8 @@ importers:
specifier: ^0.16.1
version: 0.16.1(solid-js@1.9.12)
"@solidjs/start":
- specifier: https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080
- version: https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080(crossws@0.4.5(srvx@0.11.15))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
+ specifier: 2.0.0-rc.1
+ version: 2.0.0-rc.1(crossws@0.4.10(srvx@0.11.22))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
"@tailwindcss/vite":
specifier: ^4.3.0
version: 4.3.1(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
@@ -38,8 +38,8 @@ importers:
specifier: ^17.3.1
version: 17.4.2
nitro:
- specifier: v3.0.260429-beta
- version: 3.0.260429-beta(dotenv@17.4.2)(jiti@2.7.0)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
+ specifier: ^3.0.260610-beta
+ version: 3.0.260610-beta(dotenv@17.4.2)(jiti@2.7.0)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
resolve:
specifier: 1.22.12
version: 1.22.12
@@ -121,7 +121,7 @@ importers:
version: 0.13.11(solid-js@1.9.12)
"@kobalte/solidbase":
specifier: "catalog:"
- version: 0.6.4(@solidjs/start@https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080(crossws@0.4.5(srvx@0.11.15))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(solid-js@1.9.12)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
+ version: 0.6.4(@solidjs/start@2.0.0-rc.1(crossws@0.4.10(srvx@0.11.22))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(solid-js@1.9.12)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
"@kobalte/tailwindcss":
specifier: ^0.9.0
version: 0.9.0(tailwindcss@4.3.1)
@@ -335,36 +335,18 @@ packages:
integrity: sha512-cQbnVbq0rrBwNAKegIac/t6a8nWoUAn8frnkLFW6YARaRmAQr5/Eoe6Ln2fqkUCZ40KpdrKbpSAmgrkviOxuWA==,
}
- "@emnapi/core@1.10.0":
- resolution:
- {
- integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==,
- }
-
"@emnapi/core@1.11.1":
resolution:
{
integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==,
}
- "@emnapi/runtime@1.10.0":
- resolution:
- {
- integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==,
- }
-
"@emnapi/runtime@1.11.1":
resolution:
{
integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==,
}
- "@emnapi/wasi-threads@1.2.1":
- resolution:
- {
- integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==,
- }
-
"@emnapi/wasi-threads@1.2.2":
resolution:
{
@@ -855,7 +837,6 @@ packages:
{
integrity: sha512-qW7rVdM1OyGF2UrQ1P5TkAW8LNlLsgsJCpf+XiNUVM0tdeVA8OTdBgSdmDx6fJy+URBrK4n28DUPSdJVzXk3jA==,
}
- version: 0.6.4
engines: { node: ">=22" }
peerDependencies:
"@solidjs/start": ^2.0.0
@@ -884,15 +865,6 @@ packages:
integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==,
}
- "@napi-rs/wasm-runtime@1.1.4":
- resolution:
- {
- integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==,
- }
- peerDependencies:
- "@emnapi/core": ^1.7.1
- "@emnapi/runtime": ^1.7.1
-
"@napi-rs/wasm-runtime@1.1.6":
resolution:
{
@@ -954,287 +926,334 @@ packages:
integrity: sha512-yAuSwog+HQBAXgZ60TNKEwu04y81/09mpbYBCmz1RCxnr4ObNY2JnPZI7HmALbjAhLJ8t5p+wc2JHRK93ubO4w==,
}
- "@oxc-project/types@0.128.0":
+ "@oxc-parser/binding-android-arm-eabi@0.139.0":
resolution:
{
- integrity: sha512-huv1Y/LzBJkBVHt3OlC7u0zHBW9qXf1FdD7sGmc1rXc2P1mTwHssYv7jyGx5KAACSCH+9B3Bhn6Z9luHRvf7pQ==,
+ integrity: sha512-22EsXTA3Vc7OvrF4bfT48PFln2UbxkVgrp/Tm32qLw76Dv7SmcInfClJe6yPYamnli6HiqasnESZ5ezN+X4ybg==,
}
+ engines: { node: ^20.19.0 || >=22.12.0 }
+ cpu: [arm]
+ os: [android]
- "@oxc-project/types@0.137.0":
+ "@oxc-parser/binding-android-arm64@0.139.0":
resolution:
{
- integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==,
+ integrity: sha512-uASQkZV+CUQ6xXvoMzDQyfhd8OMusdv2FyCPfAi5ZDYptesapJlw7erhpGi1Lc+U8QjQV2JUrIh7d/3su2LzmQ==,
}
+ engines: { node: ^20.19.0 || >=22.12.0 }
+ cpu: [arm64]
+ os: [android]
- "@rolldown/binding-android-arm64@1.0.0-rc.18":
+ "@oxc-parser/binding-darwin-arm64@0.139.0":
resolution:
{
- integrity: sha512-lIDyUAfD7U3+BWKzdxMbJcsYHuqXqmGz40aeRqvuAm3y5TkJSYTBW2RDrn65DJFPQqVjUAUqq5uz8urzQ8aBdQ==,
+ integrity: sha512-vuQOv2WF5pZCkdSPEExul98o853M3MCR24DpWsGrUoPJu5KcnGE34kLXY2yFwBwZwT+eN1x40Tt4q6ZzlEdNUA==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
cpu: [arm64]
- os: [android]
+ os: [darwin]
- "@rolldown/binding-android-arm64@1.1.3":
+ "@oxc-parser/binding-darwin-x64@0.139.0":
resolution:
{
- integrity: sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g==,
+ integrity: sha512-zxZB8ChS+7XactZhcyxQ292P/DNiiBaPPKYiVUlb3RC0V/hme5bokNubjcmEmbW9uTfmqLTpveAdkbe66H3pGg==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm64]
- os: [android]
+ cpu: [x64]
+ os: [darwin]
- "@rolldown/binding-darwin-arm64@1.0.0-rc.18":
+ "@oxc-parser/binding-freebsd-x64@0.139.0":
resolution:
{
- integrity: sha512-apJq2ktnGp27nSInMR5Vcj8kY6xJzDAvfdIFlpDcAK/w4cDO58qVoi1YQsES/SKiFNge/6e4CUzgjfHduYqWpQ==,
+ integrity: sha512-iw2MsoCPBQwdJqywRAGsF1jEAcGoZ+DeG2LVzt5pdUvRHqajsMF46BH0rHiWoWtMwcMSia+oQYga7fHo7u7Bcw==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm64]
- os: [darwin]
+ cpu: [x64]
+ os: [freebsd]
- "@rolldown/binding-darwin-arm64@1.1.3":
+ "@oxc-parser/binding-linux-arm-gnueabihf@0.139.0":
resolution:
{
- integrity: sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw==,
+ integrity: sha512-SwjD/k3Y5bwGJWOH313VyaDrAuaYg1Pe+4AAXCgUKvSO5IHkj+mZ0oFcOWmB5nTuOM3uwdT+leL8h4OnFlI5hw==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm64]
- os: [darwin]
+ cpu: [arm]
+ os: [linux]
- "@rolldown/binding-darwin-x64@1.0.0-rc.18":
+ "@oxc-parser/binding-linux-arm-musleabihf@0.139.0":
resolution:
{
- integrity: sha512-5Ofot8xbs+pxRHJqm9/9N/4sTQOvdrwEsmPE9pdLEEoAbdZtG6F2LMDfO1sp6ZAtXJuJV/21ew2srq3W8NXB5g==,
+ integrity: sha512-qbeygDkcvailKFhphb2YGMMXsaZIynHlPtoOrcx4NZB/tRbUKraCCMbw8dPeFtEKasfS2qWh1VnReY+Lcys1zA==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [x64]
- os: [darwin]
+ cpu: [arm]
+ os: [linux]
- "@rolldown/binding-darwin-x64@1.1.3":
+ "@oxc-parser/binding-linux-arm64-gnu@0.139.0":
resolution:
{
- integrity: sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw==,
+ integrity: sha512-SrlL02KeImKlvx/9rCeopOLH7qKI3rqKKEguK6KBwVwEGLhV/A47dW4DNigf6/LFhrwoovaiayEQryjYAI86dQ==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [x64]
- os: [darwin]
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
- "@rolldown/binding-freebsd-x64@1.0.0-rc.18":
+ "@oxc-parser/binding-linux-arm64-musl@0.139.0":
resolution:
{
- integrity: sha512-7h8eeOTT1eyqJyx64BFCnWZpNm486hGWt2sqeLLgDxA0xI1oGZ9H7gK1S85uNGmBhkdPwa/6reTxfFFKvIsebw==,
+ integrity: sha512-u9e884ChAVRmIZ1jr/m46S96FoDQnruFjISLi4Y0i6Wu/JUUmIiw7+umLyXILJsPfUuqnN5BJLe23t07+Y6+IA==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [x64]
- os: [freebsd]
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
- "@rolldown/binding-freebsd-x64@1.1.3":
+ "@oxc-parser/binding-linux-ppc64-gnu@0.139.0":
resolution:
{
- integrity: sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw==,
+ integrity: sha512-Z9tU2b3GJfAXOdirQmz4gZQkQkVjy53i77gf91l0733MQKa/qtk73KQQE2GzDtMqim+HyjpzvemmqzBtH2IJUA==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [x64]
- os: [freebsd]
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
- "@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.18":
+ "@oxc-parser/binding-linux-riscv64-gnu@0.139.0":
resolution:
{
- integrity: sha512-eRcm/HVt9U/JFu5RKAEKwGQYtDCKWLiaH6wOnsSEp6NMBb/3Os8LgHZlNyzMpFVNmiiMFlfb2zEnebfzJrHFmg==,
+ integrity: sha512-RyUbr7hzPK84YDWKs77PRYk9VBwWbsbuYsQzQWiSmLnARXTg2zntLPGfCH/1wpfUYdmGkp/6SsqTXSsYdw9Jgw==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm]
+ cpu: [riscv64]
os: [linux]
+ libc: [glibc]
- "@rolldown/binding-linux-arm-gnueabihf@1.1.3":
+ "@oxc-parser/binding-linux-riscv64-musl@0.139.0":
resolution:
{
- integrity: sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg==,
+ integrity: sha512-dcQhjtcDvtR8BgkUpt03Yz5SzxdzYvTigenIJOEsiSX6G2t6yybEMxGWjp0dOuYGror0BaqcZfTyXR58amCEig==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm]
+ cpu: [riscv64]
os: [linux]
+ libc: [musl]
- "@rolldown/binding-linux-arm64-gnu@1.0.0-rc.18":
+ "@oxc-parser/binding-linux-s390x-gnu@0.139.0":
resolution:
{
- integrity: sha512-SOrT/cT4ukTmgnrEz/Hg3m7LBnuCLW9psDeMKrimRWY4I8DmnO7Lco8W2vtqPmMkbVu8iJ+g4GFLVLLOVjJ9DQ==,
+ integrity: sha512-iuGrxysV4rGUymdKpn7bgZQ6Vix8Bi/6D/rp71HYIzphq6NKrsBhsGOYsSZte+uBFL43tXh7Xr7TM72sGliJNA==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm64]
+ cpu: [s390x]
os: [linux]
libc: [glibc]
- "@rolldown/binding-linux-arm64-gnu@1.1.3":
+ "@oxc-parser/binding-linux-x64-gnu@0.139.0":
resolution:
{
- integrity: sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA==,
+ integrity: sha512-NxJdZZyaa2JLLvNfH/iJQXfCNfKcPMylwY4ObMpBVmW4Nq+RyUpVVQXrMMelcQ6rwx3nuhF1Iga8n+eoAKGCIA==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm64]
+ cpu: [x64]
os: [linux]
libc: [glibc]
- "@rolldown/binding-linux-arm64-musl@1.0.0-rc.18":
+ "@oxc-parser/binding-linux-x64-musl@0.139.0":
resolution:
{
- integrity: sha512-QWjdxN1HJCpBTAcZ5N5F7wju3gVPzRzSpmGzx7na0c/1qpN9CFil+xt+l9lV/1M6/gqHSNXCiqPfwhVJPeLnug==,
+ integrity: sha512-ePxBvvtzISmSsJ0RIj8FNikSCn58i1jtccj7XR4U9Li4iSzhkFyYlnJ51cQTUwkairz8WMTD4SpKoot8RyTnQA==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm64]
+ cpu: [x64]
os: [linux]
libc: [musl]
- "@rolldown/binding-linux-arm64-musl@1.1.3":
+ "@oxc-parser/binding-openharmony-arm64@0.139.0":
resolution:
{
- integrity: sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w==,
+ integrity: sha512-b/c2+mPXMOxG5x16n8yf9cjor/ntQQScmYnSmLEWIWJ4rfXd5dokMxx0kliSLA+YAGq6DD3K9BWi+aFXHiiV1w==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
cpu: [arm64]
- os: [linux]
- libc: [musl]
+ os: [openharmony]
- "@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.18":
+ "@oxc-parser/binding-wasm32-wasi@0.139.0":
resolution:
{
- integrity: sha512-ugCOyj7a4d9h3q9B+wXmf6g3a68UsjGh6dob5DHevHGMwDUbhsYNbSPxJsENcIttJZ9jv7qGM2UesLw5jqIhdg==,
+ integrity: sha512-rNU0pO+/CVPC2qZ+xtX5R2cOje9Q75q3UkfgwUCPlplqxMv6Iffd5tMPGVMCLGnPINxPlmi0WPsW94HltbYvfQ==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [ppc64]
- os: [linux]
- libc: [glibc]
+ cpu: [wasm32]
- "@rolldown/binding-linux-ppc64-gnu@1.1.3":
+ "@oxc-parser/binding-win32-arm64-msvc@0.139.0":
resolution:
{
- integrity: sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw==,
+ integrity: sha512-JPEmfncZfqAFiGsAN6UZSMIBqnG8wn8buywRacFOWjP+9dZwcs03SsBp4tmyjM/4l/VoH/IuThrW1Jof3OyQUw==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [ppc64]
- os: [linux]
- libc: [glibc]
+ cpu: [arm64]
+ os: [win32]
- "@rolldown/binding-linux-s390x-gnu@1.0.0-rc.18":
+ "@oxc-parser/binding-win32-ia32-msvc@0.139.0":
resolution:
{
- integrity: sha512-kKWRhbsotpXkGbcd5dllUWg5gEXcDAa8u5YnP9AV5DYNbvJHGzzuwv7dpmhc8NqKMJldl0a+x76IHbspEpEmdA==,
+ integrity: sha512-c06dWBwEnFHof5JN7T9/ts23uATXS9czPEBO60d4xnjH2Am29Bo7OGKdVHRmcWQnw0OBxlTg9fIEXAvtcwOBfw==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [s390x]
- os: [linux]
- libc: [glibc]
+ cpu: [ia32]
+ os: [win32]
- "@rolldown/binding-linux-s390x-gnu@1.1.3":
+ "@oxc-parser/binding-win32-x64-msvc@0.139.0":
resolution:
{
- integrity: sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA==,
+ integrity: sha512-bI3/44urQjW/D495JPXe+c9d+4Q+ONi3DvDNnzwRZYTWHZ3hAlFdmirYK4mzhTfCZiAly02EbMYir7QGU+9O2Q==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [s390x]
- os: [linux]
- libc: [glibc]
+ cpu: [x64]
+ os: [win32]
+
+ "@oxc-project/types@0.137.0":
+ resolution:
+ {
+ integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==,
+ }
+
+ "@oxc-project/types@0.139.0":
+ resolution:
+ {
+ integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==,
+ }
+
+ "@rolldown/binding-android-arm64@1.1.3":
+ resolution:
+ {
+ integrity: sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g==,
+ }
+ engines: { node: ^20.19.0 || >=22.12.0 }
+ cpu: [arm64]
+ os: [android]
+
+ "@rolldown/binding-darwin-arm64@1.1.3":
+ resolution:
+ {
+ integrity: sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw==,
+ }
+ engines: { node: ^20.19.0 || >=22.12.0 }
+ cpu: [arm64]
+ os: [darwin]
- "@rolldown/binding-linux-x64-gnu@1.0.0-rc.18":
+ "@rolldown/binding-darwin-x64@1.1.3":
resolution:
{
- integrity: sha512-uCo8ElcCIAMyYAZyuIZ81oFkhTSIllNvUCHCAlbhlN4ji3uC28h7IIdlXyIvGO7HsuqnV9p3rD/bpH7XhIyhRw==,
+ integrity: sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
cpu: [x64]
- os: [linux]
- libc: [glibc]
+ os: [darwin]
- "@rolldown/binding-linux-x64-gnu@1.1.3":
+ "@rolldown/binding-freebsd-x64@1.1.3":
resolution:
{
- integrity: sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg==,
+ integrity: sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
cpu: [x64]
+ os: [freebsd]
+
+ "@rolldown/binding-linux-arm-gnueabihf@1.1.3":
+ resolution:
+ {
+ integrity: sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg==,
+ }
+ engines: { node: ^20.19.0 || >=22.12.0 }
+ cpu: [arm]
os: [linux]
- libc: [glibc]
- "@rolldown/binding-linux-x64-musl@1.0.0-rc.18":
+ "@rolldown/binding-linux-arm64-gnu@1.1.3":
resolution:
{
- integrity: sha512-XNOQZtuE6yUIvx4rwGemwh8kpL1xvU41FXy/s9K7T/3JVcqGzo3NfKM2HrbrGgfPYGFW42f07Wk++aOC6B9NWA==,
+ integrity: sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [x64]
+ cpu: [arm64]
os: [linux]
- libc: [musl]
+ libc: [glibc]
- "@rolldown/binding-linux-x64-musl@1.1.3":
+ "@rolldown/binding-linux-arm64-musl@1.1.3":
resolution:
{
- integrity: sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g==,
+ integrity: sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [x64]
+ cpu: [arm64]
os: [linux]
libc: [musl]
- "@rolldown/binding-openharmony-arm64@1.0.0-rc.18":
+ "@rolldown/binding-linux-ppc64-gnu@1.1.3":
resolution:
{
- integrity: sha512-tSn/kzrfa7tNOXr7sEacDBN4YsIqTyLqh45IO0nHDwtpKIDNDJr+VFojt+4klSpChxB29JLyduSsE0MKEwa65A==,
+ integrity: sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm64]
- os: [openharmony]
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
- "@rolldown/binding-openharmony-arm64@1.1.3":
+ "@rolldown/binding-linux-s390x-gnu@1.1.3":
resolution:
{
- integrity: sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ==,
+ integrity: sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm64]
- os: [openharmony]
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
- "@rolldown/binding-wasm32-wasi@1.0.0-rc.18":
+ "@rolldown/binding-linux-x64-gnu@1.1.3":
resolution:
{
- integrity: sha512-+J9YGmc+czgqlhYmwun3S3O0FIZhsH8ep2456xwjAdIOmuJxM7xz4P4PtrxU+Bz17a/5bqPA8o3HAAoX0teUdg==,
+ integrity: sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [wasm32]
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
- "@rolldown/binding-wasm32-wasi@1.1.3":
+ "@rolldown/binding-linux-x64-musl@1.1.3":
resolution:
{
- integrity: sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg==,
+ integrity: sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [wasm32]
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
- "@rolldown/binding-win32-arm64-msvc@1.0.0-rc.18":
+ "@rolldown/binding-openharmony-arm64@1.1.3":
resolution:
{
- integrity: sha512-zsu47DgU0FQzSwi6sU9dZoEdUv7pc1AptSEz/Z8HBg54sV0Pbs3N0+CrIbTsgiu6EyoaNN9CHboqbLaz9lhOyQ==,
+ integrity: sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
cpu: [arm64]
- os: [win32]
+ os: [openharmony]
- "@rolldown/binding-win32-arm64-msvc@1.1.3":
+ "@rolldown/binding-wasm32-wasi@1.1.3":
resolution:
{
- integrity: sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g==,
+ integrity: sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [arm64]
- os: [win32]
+ cpu: [wasm32]
- "@rolldown/binding-win32-x64-msvc@1.0.0-rc.18":
+ "@rolldown/binding-win32-arm64-msvc@1.1.3":
resolution:
{
- integrity: sha512-7H+3yqGgmnlDTRRhw/xpYY9J1kf4GC681nVc4GqKhExZTDrVVrV2tsOR9kso0fvgBdcTCcQShx4SLLoHgaLwhg==,
+ integrity: sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
- cpu: [x64]
+ cpu: [arm64]
os: [win32]
"@rolldown/binding-win32-x64-msvc@1.1.3":
@@ -1246,12 +1265,6 @@ packages:
cpu: [x64]
os: [win32]
- "@rolldown/pluginutils@1.0.0-rc.18":
- resolution:
- {
- integrity: sha512-CUY5Mnhe64xQBGZEEXQ5WyZwsc1JU3vAZLIxtrsBt3LO6UOb+C8GunVKqe9sT8NeWb4lqSaoJtp2xo6GxT1MNw==,
- }
-
"@rolldown/pluginutils@1.0.1":
resolution:
{
@@ -1519,16 +1532,14 @@ packages:
peerDependencies:
solid-js: ^1.8.6
- "@solidjs/start@https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080":
+ "@solidjs/start@2.0.0-rc.1":
resolution:
{
- integrity: sha512-gpqlCmgEBL/FbGoiiaYKUPz03un2YLog7MT7cvM0hRgXH4iG/JEzKpsGVkS0+QyRDtEgBB4qGB9BKJndGcTrWA==,
- tarball: https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080,
+ integrity: sha512-T+rVcD4Si6wyUsgwpxka8pGph8OLrIrxWK7wb4b/JyLDaCrx+q6dxTJ3TxCljCgw58NWY+grmGllEgAcTm783g==,
}
- version: 2.0.0-alpha.2
- engines: { node: ">=22" }
+ engines: { node: ">=24" }
peerDependencies:
- vite: ^7
+ vite: ^8 || ^9
"@swc/helpers@0.5.21":
resolution:
@@ -1683,12 +1694,6 @@ packages:
peerDependencies:
vite: ^5.2.0 || ^6 || ^7 || ^8
- "@tybys/wasm-util@0.10.2":
- resolution:
- {
- integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==,
- }
-
"@tybys/wasm-util@0.10.3":
resolution:
{
@@ -2179,10 +2184,10 @@ packages:
}
engines: { node: ">= 8" }
- crossws@0.4.5:
+ crossws@0.4.10:
resolution:
{
- integrity: sha512-wUR89x/Rw7/8t+vn0CmGDYM9TD6VtARGb0LD5jq2wjtMy1vCP4M+sm6N6TigWeTYvnA8MoW29NqqXD0ep0rfBA==,
+ integrity: sha512-pz3oubH/dt12KjqsUB0IuXW4nwRDQ583iDsP4555Cpdqx0NoU7pGlWBcayyFI8f/l/idRpgjMEfwuOxSWJYlIA==,
}
peerDependencies:
srvx: ">=0.11.5"
@@ -2378,20 +2383,26 @@ packages:
}
engines: { node: ">=0.12" }
- env-runner@0.1.7:
+ env-runner@0.1.16:
resolution:
{
- integrity: sha512-i7h96jxETJYhXy5grgHNJ9xNzCzWIn9Ck/VkkYgOlE4gOqknsLX3CmlVb5LmwNex8sOoLFVZLz+TIw/+b5rktA==,
+ integrity: sha512-2LRJM4P2KLX6J83QZZrMqvgCDt/D5ea7wPcI3yYiy5cG/9rX5QwdwZFx0D7ktWnjdRyZxYjttGGorb5nFqb1CA==,
}
hasBin: true
peerDependencies:
- "@netlify/runtime": ^4
- miniflare: ^4.20260317.3
+ "@netlify/runtime": ^4.1.23
+ "@vercel/queue": ">=0.2.0"
+ miniflare: ^4.20260515.0
+ wrangler: ^4.0.0
peerDependenciesMeta:
"@netlify/runtime":
optional: true
+ "@vercel/queue":
+ optional: true
miniflare:
optional: true
+ wrangler:
+ optional: true
error-stack-parser@2.1.4:
resolution:
@@ -2406,12 +2417,6 @@ packages:
}
engines: { node: ">= 0.4" }
- es-module-lexer@2.1.0:
- resolution:
- {
- integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==,
- }
-
esast-util-from-estree@2.0.0:
resolution:
{
@@ -2604,12 +2609,6 @@ packages:
integrity: sha512-2wZjC8OQ3TaVEMcBtYY4Va3lo6J+Ai9jf3d4dbhURMJcU4Pbqe6EcHe424MIZI0VHUA1bR6xdpoHYi3yxokWqA==,
}
- exsolve@1.0.8:
- resolution:
- {
- integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==,
- }
-
exsolve@1.1.0:
resolution:
{
@@ -2780,10 +2779,10 @@ packages:
}
engines: { node: ">=6.0" }
- h3@2.0.1-rc.16:
+ h3@2.0.1-rc.22:
resolution:
{
- integrity: sha512-h+pjvyujdo9way8qj6FUbhaQcHlR8FEq65EhTX9ViT5pK8aLj68uFl4hBkF+hsTJAH+H1END2Yv6hTIsabGfag==,
+ integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==,
}
engines: { node: ">=20.11.1" }
hasBin: true
@@ -2793,15 +2792,15 @@ packages:
crossws:
optional: true
- h3@2.0.1-rc.22:
+ h3@2.0.1-rc.25:
resolution:
{
- integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==,
+ integrity: sha512-uIK++Up28xDt4n0+bSWfVssRivNXpUmMmA6CCiK6j9+utLcBMcFK97Gn9PlSZwAPW9oLy3CjGJ4ag40CY9YYtQ==,
}
engines: { node: ">=20.11.1" }
hasBin: true
peerDependencies:
- crossws: ^0.4.1
+ crossws: ^0.4.9
peerDependenciesMeta:
crossws:
optional: true
@@ -2940,10 +2939,10 @@ packages:
integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==,
}
- httpxy@0.5.1:
+ httpxy@0.5.5:
resolution:
{
- integrity: sha512-JPhqYiixe1A1I+MXDewWDZqeudBGU8Q9jCHYN8ML+779RQzLjTi78HBvWz4jMxUD6h2/vUL12g4q/mFM0OUw1A==,
+ integrity: sha512-uDjmnPyp1q4Sgzf3w+J/Fc6UqcCEj0x4Wjp7OqK5dGhNeDgpyrAmnS6ey8QWrX3SWDon2DMKf9sBa5X9+CVyMA==,
}
ignore@5.3.2:
@@ -3702,25 +3701,25 @@ packages:
integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==,
}
- nf3@0.3.16:
+ nf3@0.3.22:
resolution:
{
- integrity: sha512-Gs0xRPpUm2nDkqbi40NJ9g7qDIcjcJzgExiydnq6LAyqhI2jfno8wG3NKTL+IiJsx799UHOb1CnSd4Wg4SG4Pw==,
+ integrity: sha512-NOcqlHu22X1rUakd0SrqllP8kb3LWFmSAi1svTxaKxz+yB604xlaOmUfI3oO+RkODvaocKDDy8bgthnZL8hrkw==,
}
- nitro@3.0.260429-beta:
+ nitro@3.0.260610-beta:
resolution:
{
- integrity: sha512-KweLVCUN5X9v9g+4yxAyRcz3FcOlnjmt9FyrAIWDxJETJmNT7I0JV0clgsONjo2nI0U5gwedXYA3RaNtF5XWzg==,
+ integrity: sha512-KPb4L5yaF/Rx/xoGMpgHRJvZhbhGiqbRKOwwPLCH9jKTKTsEUHLjnJas85AeCzaswqa8Wi52eQBtRsODC4PS0Q==,
}
engines: { node: ^20.19.0 || >=22.12.0 }
hasBin: true
peerDependencies:
- "@vercel/queue": ^0.1.6
+ "@vercel/queue": ^0.3.0
dotenv: "*"
giget: "*"
- jiti: ^2.6.1
- rollup: ^4.60.2
+ jiti: ^2.7.0
+ rollup: ^4.61.1
vite: ^7 || ^8
xml2js: ^0.6.2
zephyr-agent: ^0.2.0
@@ -3754,10 +3753,10 @@ packages:
integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==,
}
- ocache@0.1.4:
+ ocache@0.1.5:
resolution:
{
- integrity: sha512-e7geNdWjxSnvsSgvLuPvgKgu7ubM10ZmTPOgpr7mz2BXYtvjMKTiLhjFi/gWU8chkuP6hNkZBsa9LzOusyaqkQ==,
+ integrity: sha512-kNNnkkVQup/QDvmTz8Q84wc2ntiyoVHDxa6eHWKt5qdGAmFRBIxy83rxgCYEjW0x06UJ9E3P6VgM2yY4rOBH4w==,
}
ofetch@2.0.0-alpha.3:
@@ -3797,6 +3796,13 @@ packages:
}
engines: { node: ">= 0.8.0" }
+ oxc-parser@0.139.0:
+ resolution:
+ {
+ integrity: sha512-cf1TKZN+zc0lwqigeyXKzKVk5+vNRe99Or2+wVJsXLdlhJgC+gsIniYDfj/ZEBzCJ8Xm21ZG6YtMbR262CcS2w==,
+ }
+ engines: { node: ^20.19.0 || >=22.12.0 }
+
p-limit@3.1.0:
resolution:
{
@@ -4196,14 +4202,6 @@ packages:
}
engines: { iojs: ">=1.0.0", node: ">=0.10.0" }
- rolldown@1.0.0-rc.18:
- resolution:
- {
- integrity: sha512-phmyKBpuBdRYDf4hgyynGAYn/rDDe+iZXKVJ7WX5b1zQzpLkP5oJRPGsfJuHdzPMlyyEO/4sPW6yfSx2gf7lVg==,
- }
- engines: { node: ^20.19.0 || >=22.12.0 }
- hasBin: true
-
rolldown@1.1.3:
resolution:
{
@@ -4218,6 +4216,12 @@ packages:
integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==,
}
+ rou3@0.9.1:
+ resolution:
+ {
+ integrity: sha512-z/sSmzvtwMDDnxsPVhfWMuG6F6mbmhFDXoVqLmMfbpDD9qfV3GDmSQpf0+W296/ZDIpW2wcMmBfpVFzcnOi/nA==,
+ }
+
run-parallel@1.2.0:
resolution:
{
@@ -4398,6 +4402,14 @@ packages:
engines: { node: ">=20.16.0" }
hasBin: true
+ srvx@0.11.22:
+ resolution:
+ {
+ integrity: sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==,
+ }
+ engines: { node: ">=20.16.0" }
+ hasBin: true
+
stackframe@1.3.4:
resolution:
{
@@ -5081,33 +5093,17 @@ snapshots:
"@docsearch/css@3.9.0": {}
- "@emnapi/core@1.10.0":
- dependencies:
- "@emnapi/wasi-threads": 1.2.1
- tslib: 2.8.1
- optional: true
-
"@emnapi/core@1.11.1":
dependencies:
"@emnapi/wasi-threads": 1.2.2
tslib: 2.8.1
optional: true
- "@emnapi/runtime@1.10.0":
- dependencies:
- tslib: 2.8.1
- optional: true
-
"@emnapi/runtime@1.11.1":
dependencies:
tslib: 2.8.1
optional: true
- "@emnapi/wasi-threads@1.2.1":
- dependencies:
- tslib: 2.8.1
- optional: true
-
"@emnapi/wasi-threads@1.2.2":
dependencies:
tslib: 2.8.1
@@ -5342,7 +5338,7 @@ snapshots:
solid-presence: 0.1.8(solid-js@1.9.12)
solid-prevent-scroll: 0.1.10(solid-js@1.9.12)
- "@kobalte/solidbase@0.6.4(@solidjs/start@https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080(crossws@0.4.5(srvx@0.11.15))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(solid-js@1.9.12)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))":
+ "@kobalte/solidbase@0.6.4(@solidjs/start@2.0.0-rc.1(crossws@0.4.10(srvx@0.11.22))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(solid-js@1.9.12)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))":
dependencies:
"@alloc/quick-lru": 5.2.0
"@bprogress/core": 1.3.4
@@ -5366,7 +5362,7 @@ snapshots:
"@solid-primitives/storage": 4.3.4(solid-js@1.9.12)
"@solidjs/meta": 0.29.4(solid-js@1.9.12)
"@solidjs/router": 0.16.1(solid-js@1.9.12)
- "@solidjs/start": https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080(crossws@0.4.5(srvx@0.11.15))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
+ "@solidjs/start": 2.0.0-rc.1(crossws@0.4.10(srvx@0.11.22))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
cross-spawn: 7.0.6
diff: 8.0.4
esast-util-from-js: 2.0.1
@@ -5463,13 +5459,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- "@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)":
- dependencies:
- "@emnapi/core": 1.10.0
- "@emnapi/runtime": 1.10.0
- "@tybys/wasm-util": 0.10.2
- optional: true
-
"@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)":
dependencies:
"@emnapi/core": 1.11.1
@@ -5507,87 +5496,108 @@ snapshots:
"@orama/oramacore-events-parser@0.0.5": {}
- "@oxc-project/types@0.128.0": {}
+ "@oxc-parser/binding-android-arm-eabi@0.139.0":
+ optional: true
- "@oxc-project/types@0.137.0": {}
+ "@oxc-parser/binding-android-arm64@0.139.0":
+ optional: true
- "@rolldown/binding-android-arm64@1.0.0-rc.18":
+ "@oxc-parser/binding-darwin-arm64@0.139.0":
optional: true
- "@rolldown/binding-android-arm64@1.1.3":
+ "@oxc-parser/binding-darwin-x64@0.139.0":
optional: true
- "@rolldown/binding-darwin-arm64@1.0.0-rc.18":
+ "@oxc-parser/binding-freebsd-x64@0.139.0":
optional: true
- "@rolldown/binding-darwin-arm64@1.1.3":
+ "@oxc-parser/binding-linux-arm-gnueabihf@0.139.0":
optional: true
- "@rolldown/binding-darwin-x64@1.0.0-rc.18":
+ "@oxc-parser/binding-linux-arm-musleabihf@0.139.0":
optional: true
- "@rolldown/binding-darwin-x64@1.1.3":
+ "@oxc-parser/binding-linux-arm64-gnu@0.139.0":
optional: true
- "@rolldown/binding-freebsd-x64@1.0.0-rc.18":
+ "@oxc-parser/binding-linux-arm64-musl@0.139.0":
optional: true
- "@rolldown/binding-freebsd-x64@1.1.3":
+ "@oxc-parser/binding-linux-ppc64-gnu@0.139.0":
optional: true
- "@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.18":
+ "@oxc-parser/binding-linux-riscv64-gnu@0.139.0":
optional: true
- "@rolldown/binding-linux-arm-gnueabihf@1.1.3":
+ "@oxc-parser/binding-linux-riscv64-musl@0.139.0":
optional: true
- "@rolldown/binding-linux-arm64-gnu@1.0.0-rc.18":
+ "@oxc-parser/binding-linux-s390x-gnu@0.139.0":
optional: true
- "@rolldown/binding-linux-arm64-gnu@1.1.3":
+ "@oxc-parser/binding-linux-x64-gnu@0.139.0":
optional: true
- "@rolldown/binding-linux-arm64-musl@1.0.0-rc.18":
+ "@oxc-parser/binding-linux-x64-musl@0.139.0":
optional: true
- "@rolldown/binding-linux-arm64-musl@1.1.3":
+ "@oxc-parser/binding-openharmony-arm64@0.139.0":
optional: true
- "@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.18":
+ "@oxc-parser/binding-wasm32-wasi@0.139.0":
+ dependencies:
+ "@emnapi/core": 1.11.1
+ "@emnapi/runtime": 1.11.1
+ "@napi-rs/wasm-runtime": 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)
optional: true
- "@rolldown/binding-linux-ppc64-gnu@1.1.3":
+ "@oxc-parser/binding-win32-arm64-msvc@0.139.0":
optional: true
- "@rolldown/binding-linux-s390x-gnu@1.0.0-rc.18":
+ "@oxc-parser/binding-win32-ia32-msvc@0.139.0":
optional: true
- "@rolldown/binding-linux-s390x-gnu@1.1.3":
+ "@oxc-parser/binding-win32-x64-msvc@0.139.0":
optional: true
- "@rolldown/binding-linux-x64-gnu@1.0.0-rc.18":
+ "@oxc-project/types@0.137.0": {}
+
+ "@oxc-project/types@0.139.0": {}
+
+ "@rolldown/binding-android-arm64@1.1.3":
optional: true
- "@rolldown/binding-linux-x64-gnu@1.1.3":
+ "@rolldown/binding-darwin-arm64@1.1.3":
optional: true
- "@rolldown/binding-linux-x64-musl@1.0.0-rc.18":
+ "@rolldown/binding-darwin-x64@1.1.3":
optional: true
- "@rolldown/binding-linux-x64-musl@1.1.3":
+ "@rolldown/binding-freebsd-x64@1.1.3":
optional: true
- "@rolldown/binding-openharmony-arm64@1.0.0-rc.18":
+ "@rolldown/binding-linux-arm-gnueabihf@1.1.3":
optional: true
- "@rolldown/binding-openharmony-arm64@1.1.3":
+ "@rolldown/binding-linux-arm64-gnu@1.1.3":
optional: true
- "@rolldown/binding-wasm32-wasi@1.0.0-rc.18":
- dependencies:
- "@emnapi/core": 1.10.0
- "@emnapi/runtime": 1.10.0
- "@napi-rs/wasm-runtime": 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
+ "@rolldown/binding-linux-arm64-musl@1.1.3":
+ optional: true
+
+ "@rolldown/binding-linux-ppc64-gnu@1.1.3":
+ optional: true
+
+ "@rolldown/binding-linux-s390x-gnu@1.1.3":
+ optional: true
+
+ "@rolldown/binding-linux-x64-gnu@1.1.3":
+ optional: true
+
+ "@rolldown/binding-linux-x64-musl@1.1.3":
+ optional: true
+
+ "@rolldown/binding-openharmony-arm64@1.1.3":
optional: true
"@rolldown/binding-wasm32-wasi@1.1.3":
@@ -5597,20 +5607,12 @@ snapshots:
"@napi-rs/wasm-runtime": 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)
optional: true
- "@rolldown/binding-win32-arm64-msvc@1.0.0-rc.18":
- optional: true
-
"@rolldown/binding-win32-arm64-msvc@1.1.3":
optional: true
- "@rolldown/binding-win32-x64-msvc@1.0.0-rc.18":
- optional: true
-
"@rolldown/binding-win32-x64-msvc@1.1.3":
optional: true
- "@rolldown/pluginutils@1.0.0-rc.18": {}
-
"@rolldown/pluginutils@1.0.1": {}
"@shikijs/core@1.29.2":
@@ -5790,7 +5792,7 @@ snapshots:
dependencies:
solid-js: 1.9.12
- "@solidjs/start@https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2080(crossws@0.4.5(srvx@0.11.15))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))":
+ "@solidjs/start@2.0.0-rc.1(crossws@0.4.10(srvx@0.11.22))(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))":
dependencies:
"@babel/core": 7.29.0
"@babel/traverse": 7.29.0
@@ -5801,12 +5803,11 @@ snapshots:
cookie-es: 2.0.1
defu: 6.1.7
error-stack-parser: 2.1.4
- es-module-lexer: 2.1.0
- esbuild: 0.27.7
fast-glob: 3.3.3
- h3: 2.0.1-rc.16(crossws@0.4.5(srvx@0.11.15))
+ h3: 2.0.1-rc.25(crossws@0.4.10(srvx@0.11.22))
html-to-image: 1.11.13
micromatch: 4.0.8
+ oxc-parser: 0.139.0
path-to-regexp: 8.4.2
pathe: 2.0.3
radix3: 1.1.2
@@ -5815,7 +5816,7 @@ snapshots:
shiki: 1.29.2
solid-js: 1.9.12
source-map-js: 1.2.1
- srvx: 0.11.15
+ srvx: 0.11.22
terracotta: 1.1.0(solid-js@1.9.12)
vite: 8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)
vite-plugin-solid: 2.11.12(solid-js@1.9.12)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))
@@ -5901,11 +5902,6 @@ snapshots:
tailwindcss: 4.3.1
vite: 8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)
- "@tybys/wasm-util@0.10.2":
- dependencies:
- tslib: 2.8.1
- optional: true
-
"@tybys/wasm-util@0.10.3":
dependencies:
tslib: 2.8.1
@@ -6237,9 +6233,9 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
- crossws@0.4.5(srvx@0.11.15):
+ crossws@0.4.10(srvx@0.11.22):
optionalDependencies:
- srvx: 0.11.15
+ srvx: 0.11.22
css-select@5.2.2:
dependencies:
@@ -6316,12 +6312,12 @@ snapshots:
entities@6.0.1: {}
- env-runner@0.1.7:
+ env-runner@0.1.16:
dependencies:
- crossws: 0.4.5(srvx@0.11.15)
- exsolve: 1.0.8
- httpxy: 0.5.1
- srvx: 0.11.15
+ crossws: 0.4.10(srvx@0.11.22)
+ exsolve: 1.1.0
+ httpxy: 0.5.5
+ srvx: 0.11.22
error-stack-parser@2.1.4:
dependencies:
@@ -6329,8 +6325,6 @@ snapshots:
es-errors@1.3.0: {}
- es-module-lexer@2.1.0: {}
-
esast-util-from-estree@2.0.0:
dependencies:
"@types/estree-jsx": 1.0.5
@@ -6373,6 +6367,7 @@ snapshots:
"@esbuild/win32-arm64": 0.27.7
"@esbuild/win32-ia32": 0.27.7
"@esbuild/win32-x64": 0.27.7
+ optional: true
escalade@3.2.0: {}
@@ -6517,8 +6512,6 @@ snapshots:
"@expressive-code/plugin-shiki": 0.41.7
"@expressive-code/plugin-text-markers": 0.41.7
- exsolve@1.0.8: {}
-
exsolve@1.1.0: {}
extend-shallow@2.0.1:
@@ -6603,19 +6596,19 @@ snapshots:
section-matter: 1.0.0
strip-bom-string: 1.0.0
- h3@2.0.1-rc.16(crossws@0.4.5(srvx@0.11.15)):
+ h3@2.0.1-rc.22(crossws@0.4.10(srvx@0.11.22)):
dependencies:
rou3: 0.8.1
srvx: 0.11.15
optionalDependencies:
- crossws: 0.4.5(srvx@0.11.15)
+ crossws: 0.4.10(srvx@0.11.22)
- h3@2.0.1-rc.22(crossws@0.4.5(srvx@0.11.15)):
+ h3@2.0.1-rc.25(crossws@0.4.10(srvx@0.11.22)):
dependencies:
- rou3: 0.8.1
- srvx: 0.11.15
+ rou3: 0.9.1
+ srvx: 0.11.22
optionalDependencies:
- crossws: 0.4.5(srvx@0.11.15)
+ crossws: 0.4.10(srvx@0.11.22)
hasown@2.0.3:
dependencies:
@@ -6787,7 +6780,7 @@ snapshots:
domutils: 3.2.2
entities: 4.5.0
- httpxy@0.5.1: {}
+ httpxy@0.5.5: {}
ignore@5.3.2: {}
@@ -7450,22 +7443,22 @@ snapshots:
natural-compare@1.4.0: {}
- nf3@0.3.16: {}
+ nf3@0.3.22: {}
- nitro@3.0.260429-beta(dotenv@17.4.2)(jiti@2.7.0)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)):
+ nitro@3.0.260610-beta(dotenv@17.4.2)(jiti@2.7.0)(vite@8.1.3(@types/node@25.9.1)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)):
dependencies:
consola: 3.4.2
- crossws: 0.4.5(srvx@0.11.15)
+ crossws: 0.4.10(srvx@0.11.22)
db0: 0.3.4
- env-runner: 0.1.7
- h3: 2.0.1-rc.22(crossws@0.4.5(srvx@0.11.15))
+ env-runner: 0.1.16
+ h3: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.22))
hookable: 6.1.1
- nf3: 0.3.16
- ocache: 0.1.4
+ nf3: 0.3.22
+ ocache: 0.1.5
ofetch: 2.0.0-alpha.3
ohash: 2.0.11
- rolldown: 1.0.0-rc.18
- srvx: 0.11.15
+ rolldown: 1.1.3
+ srvx: 0.11.22
unenv: 2.0.0-rc.24
unstorage: 2.0.0-alpha.7(db0@0.3.4)(ofetch@2.0.0-alpha.3)
optionalDependencies:
@@ -7502,6 +7495,7 @@ snapshots:
- mysql2
- sqlite3
- uploadthing
+ - wrangler
node-releases@2.0.38: {}
@@ -7509,7 +7503,7 @@ snapshots:
dependencies:
boolbase: 1.0.0
- ocache@0.1.4:
+ ocache@0.1.5:
dependencies:
ohash: 2.0.11
@@ -7540,6 +7534,31 @@ snapshots:
type-check: 0.4.0
word-wrap: 1.2.5
+ oxc-parser@0.139.0:
+ dependencies:
+ "@oxc-project/types": 0.139.0
+ optionalDependencies:
+ "@oxc-parser/binding-android-arm-eabi": 0.139.0
+ "@oxc-parser/binding-android-arm64": 0.139.0
+ "@oxc-parser/binding-darwin-arm64": 0.139.0
+ "@oxc-parser/binding-darwin-x64": 0.139.0
+ "@oxc-parser/binding-freebsd-x64": 0.139.0
+ "@oxc-parser/binding-linux-arm-gnueabihf": 0.139.0
+ "@oxc-parser/binding-linux-arm-musleabihf": 0.139.0
+ "@oxc-parser/binding-linux-arm64-gnu": 0.139.0
+ "@oxc-parser/binding-linux-arm64-musl": 0.139.0
+ "@oxc-parser/binding-linux-ppc64-gnu": 0.139.0
+ "@oxc-parser/binding-linux-riscv64-gnu": 0.139.0
+ "@oxc-parser/binding-linux-riscv64-musl": 0.139.0
+ "@oxc-parser/binding-linux-s390x-gnu": 0.139.0
+ "@oxc-parser/binding-linux-x64-gnu": 0.139.0
+ "@oxc-parser/binding-linux-x64-musl": 0.139.0
+ "@oxc-parser/binding-openharmony-arm64": 0.139.0
+ "@oxc-parser/binding-wasm32-wasi": 0.139.0
+ "@oxc-parser/binding-win32-arm64-msvc": 0.139.0
+ "@oxc-parser/binding-win32-ia32-msvc": 0.139.0
+ "@oxc-parser/binding-win32-x64-msvc": 0.139.0
+
p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
@@ -7800,27 +7819,6 @@ snapshots:
reusify@1.1.0: {}
- rolldown@1.0.0-rc.18:
- dependencies:
- "@oxc-project/types": 0.128.0
- "@rolldown/pluginutils": 1.0.0-rc.18
- optionalDependencies:
- "@rolldown/binding-android-arm64": 1.0.0-rc.18
- "@rolldown/binding-darwin-arm64": 1.0.0-rc.18
- "@rolldown/binding-darwin-x64": 1.0.0-rc.18
- "@rolldown/binding-freebsd-x64": 1.0.0-rc.18
- "@rolldown/binding-linux-arm-gnueabihf": 1.0.0-rc.18
- "@rolldown/binding-linux-arm64-gnu": 1.0.0-rc.18
- "@rolldown/binding-linux-arm64-musl": 1.0.0-rc.18
- "@rolldown/binding-linux-ppc64-gnu": 1.0.0-rc.18
- "@rolldown/binding-linux-s390x-gnu": 1.0.0-rc.18
- "@rolldown/binding-linux-x64-gnu": 1.0.0-rc.18
- "@rolldown/binding-linux-x64-musl": 1.0.0-rc.18
- "@rolldown/binding-openharmony-arm64": 1.0.0-rc.18
- "@rolldown/binding-wasm32-wasi": 1.0.0-rc.18
- "@rolldown/binding-win32-arm64-msvc": 1.0.0-rc.18
- "@rolldown/binding-win32-x64-msvc": 1.0.0-rc.18
-
rolldown@1.1.3:
dependencies:
"@oxc-project/types": 0.137.0
@@ -7844,6 +7842,8 @@ snapshots:
rou3@0.8.1: {}
+ rou3@0.9.1: {}
+
run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
@@ -7945,6 +7945,8 @@ snapshots:
srvx@0.11.15: {}
+ srvx@0.11.22: {}
+
stackframe@1.3.4: {}
stringify-entities@4.0.4:
diff --git a/src/routes/solid-start/v2/(0)building-your-application/(2)css-and-styling.mdx b/src/routes/solid-start/v2/(0)building-your-application/(2)css-and-styling.mdx
index 570e26eef..6afe086de 100644
--- a/src/routes/solid-start/v2/(0)building-your-application/(2)css-and-styling.mdx
+++ b/src/routes/solid-start/v2/(0)building-your-application/(2)css-and-styling.mdx
@@ -16,7 +16,7 @@ description: >-
solutions. Implement scoped styles and design systems.
---
-SolidStart 2.0 introduces a completely revamped CSS rendering mechanism:
+SolidStart v2 introduces a completely revamped CSS rendering mechanism:
- CSS deduplication during server-side rendering works more consistently across the board.
- Hot module replacement (HMR) of route CSS is now directly managed by Vite instead of SolidStart.
@@ -144,7 +144,7 @@ export default function About() {
## Lazy loading
-[Lazy](https://docs.solidjs.com/reference/component-apis/lazy) loading components with CSS is now fully supported in SolidStart 2.0 and no longer results in flashes of unstyled content (FOUC):
+[Lazy](https://docs.solidjs.com/reference/component-apis/lazy) loading components with CSS is now fully supported in SolidStart v2 and no longer results in flashes of unstyled content (FOUC):
```tsx title="App.tsx" tab="component"
import { lazy } from "solid-js";
diff --git a/src/routes/solid-start/v2/(0)building-your-application/(5)head-and-metadata.mdx b/src/routes/solid-start/v2/(0)building-your-application/(5)head-and-metadata.mdx
new file mode 100644
index 000000000..ad2c5d156
--- /dev/null
+++ b/src/routes/solid-start/v2/(0)building-your-application/(5)head-and-metadata.mdx
@@ -0,0 +1,99 @@
+---
+title: Head and metadata
+use_cases: >-
+ seo optimization, page titles, meta tags, og tags, social sharing, search
+ engine visibility, dynamic metadata
+tags:
+ - seo
+ - metadata
+ - head
+ - title
+ - meta
+ - og-tags
+version: "2.0"
+description: >-
+ Manage SEO and metadata in SolidStart with dynamic titles, meta tags, and Open
+ Graph tags.
+---
+
+SolidStart does not bundle a metadata API. Use [`@solidjs/meta`](/solid-meta) to manage document titles, metadata, links, styles, and other elements in `
`.
+
+```package-install
+@solidjs/meta
+```
+
+## Add the provider
+
+Place `MetaProvider` in the router root so route metadata is collected during server rendering and updated during client navigation.
+
+```tsx title="src/app.tsx" {8,12}
+import { MetaProvider } from "@solidjs/meta";
+import { Router } from "@solidjs/router";
+import { FileRoutes } from "@solidjs/start/router";
+import { Suspense } from "solid-js";
+
+export default function App() {
+ return (
+ (
+
+ {props.children}
+
+ )}
+ >
+
+
+ );
+}
+```
+
+## Set route metadata
+
+Metadata components can be rendered from any route below `MetaProvider`. They are removed or updated when the route changes.
+
+```tsx title="src/routes/about.tsx"
+import { Meta, Title } from "@solidjs/meta";
+
+export default function About() {
+ return (
+ <>
+ About | My site
+
+
+ About
+ >
+ );
+}
+```
+
+## Use asynchronous data
+
+Metadata can read the same query result as the route. Wrap the rendered data in `Suspense` or `Show` when it may not be available immediately.
+
+```tsx title="src/routes/users/[id].tsx"
+import { Title } from "@solidjs/meta";
+import { createAsync, query, type RouteSectionProps } from "@solidjs/router";
+import { Show } from "solid-js";
+
+const getUser = query(async (id: string) => {
+ "use server";
+ return { id, name: `User ${id}` };
+}, "user");
+
+export default function User(props: RouteSectionProps) {
+ const user = createAsync(() => getUser(props.params.id));
+
+ return (
+
+ {(value) => (
+ <>
+ {value().name}
+ {value().name}
+ >
+ )}
+
+ );
+}
+```
+
+See the [`@solidjs/meta` documentation](/solid-meta) for all supported head elements and provider behavior.
diff --git a/src/routes/solid-start/v2/(0)building-your-application/(6)route-prerendering.mdx b/src/routes/solid-start/v2/(0)building-your-application/(6)route-prerendering.mdx
new file mode 100644
index 000000000..1d4c3e00f
--- /dev/null
+++ b/src/routes/solid-start/v2/(0)building-your-application/(6)route-prerendering.mdx
@@ -0,0 +1,57 @@
+---
+title: Route pre-rendering
+use_cases: >-
+ static site generation, ssg, blog sites, documentation, marketing pages,
+ performance optimization, seo improvement
+tags:
+ - prerender
+ - ssg
+ - static
+ - performance
+ - build
+ - seo
+version: "2.0"
+description: >-
+ Pre-render SolidStart routes to static HTML with Nitro v3.
+---
+
+Route pre-rendering produces static HTML during `vite build`. Nitro writes the generated files to `.output/public`, where a CDN or server can serve them without rendering the route on each request.
+
+Configure prerendering through Nitro's top-level Vite configuration.
+
+## Pre-render selected routes
+
+```tsx title="vite.config.ts"
+import { nitro } from "nitro/vite";
+import { defineConfig } from "vite";
+import { solidStart } from "@solidjs/start/config";
+
+export default defineConfig({
+ plugins: [solidStart(), nitro()],
+ nitro: {
+ prerender: {
+ routes: ["/", "/about"],
+ },
+ },
+});
+```
+
+## Crawl links
+
+Set `crawlLinks` to start at `/` and follow links found in rendered HTML. Add `routes` when the crawler needs additional entry points.
+
+```tsx title="vite.config.ts"
+export default defineConfig({
+ plugins: [solidStart(), nitro()],
+ nitro: {
+ prerender: {
+ crawlLinks: true,
+ failOnError: true,
+ },
+ },
+});
+```
+
+Dynamic routes that are not linked from a crawled page must be listed explicitly or discovered from another entry route.
+
+For retry, concurrency, ignore, and output-path options, see [Nitro's prerender configuration](https://nitro.build/config#prerender).
diff --git a/src/routes/solid-start/v2/(0)building-your-application/(7)static-assets.mdx b/src/routes/solid-start/v2/(0)building-your-application/(7)static-assets.mdx
new file mode 100644
index 000000000..0f4fa1290
--- /dev/null
+++ b/src/routes/solid-start/v2/(0)building-your-application/(7)static-assets.mdx
@@ -0,0 +1,93 @@
+---
+title: Static assets
+use_cases: >-
+ images, fonts, documents, favicon, robots.txt, service workers, media files,
+ public resources
+tags:
+ - assets
+ - images
+ - public
+ - static
+ - media
+ - files
+version: "2.0"
+description: >-
+ Manage static assets in SolidStart using the public directory or imports.
+ Serve images, fonts, documents, and media files.
+---
+
+Within SolidStart there are two ways to import static assets into your project: using the public directory and using imports.
+
+## Public directory
+
+Rich web applications use assets to create visuals.
+In SolidStart, the `/public` directory can be used to store static assets.
+These assets are served at the exact path they are in, relative to the public directory:
+
+```
+|-- public
+| favicon.ico -> /favicon.ico
+| |-- images
+| | |-- logo.png -> /images/logo.png
+| | |-- background.png -> /images/background.png
+| |-- models
+| | |-- player.gltf -> /models/player.gltf
+| |-- documents
+| | |-- report.pdf -> /documents/report.pdf
+```
+
+If you would like to reference an asset in the public directory, you can use the absolute path to the asset:
+
+```tsx { 5 }
+export default function About() {
+ return (
+ <>
+ About
+
+ >
+ );
+}
+```
+
+This is ideal when you want to have human-readable, stable references to static assets.
+This can be useful for assets such as:
+
+- documents
+- service workers
+- images, audio, and video
+- manifest files
+- metadata files (e.g., `robots.txt`, sitemaps)
+- favicon
+
+## Importing assets
+
+Vite provides a way to import assets directly into your Solid components:
+
+```tsx
+import logo from "./solid.png";
+
+export default function About() {
+ return (
+ <>
+ About
+
+ // Renders
+
+ >
+ );
+}
+```
+
+When you use imports, Vite will create a hashed filename.
+For example, `solid.png` will become `solid.2d8efhg.png`.
+
+## Public directory versus imports
+
+The public directory and imports are both valid ways to include static assets in your project.
+The driver to use one over the other is based on your use case.
+
+For dynamic updates to your assets, using the public directory is the best choice.
+It allows you to maintain full control over the asset URL paths, ensuring that the links remain consistent even when the assets are updated.
+
+When using imports, the filename is hashed and therefore will not be predictable over time.
+This can be beneficial for cache busting but detrimental if you want to send someone a link to the asset.
diff --git a/src/routes/solid-start/v2/(0)index.mdx b/src/routes/solid-start/v2/(0)index.mdx
index 072ddb76d..8b4457880 100644
--- a/src/routes/solid-start/v2/(0)index.mdx
+++ b/src/routes/solid-start/v2/(0)index.mdx
@@ -16,7 +16,7 @@ description: >-
Vite-based configuration.
---
-SolidStart 2.0 builds a full-stack app on top of [Solid](/) and [Solid Router](/solid-router), with file-based routing, server functions, and Vite-based configuration.
+SolidStart v2 builds a full-stack app on top of [Solid v1](/), [Solid Router](/solid-router), and [Vite 8+](https://vite.dev). It uses Vite's Environment API for client and server builds and works with deployment Vite plugins such as [Nitro v3](https://nitro.build) and the [Cloudflare Vite plugin](https://www.npmjs.com/package/@cloudflare/vite-plugin).
The framework is split into a handful of entry points:
@@ -26,6 +26,8 @@ The framework is split into a handful of entry points:
- `@solidjs/start/http` for request, response, cookie, and session helpers
- `@solidjs/start/middleware` for middleware composition
+SolidStart v2 requires Node.js 24 or newer and Vite 8 or 9.
+
## What v2 keeps
The core model carries over from v1:
@@ -37,6 +39,6 @@ The core model carries over from v1:
## What changed from v1
-Configuration moved from `app.config.ts` to `vite.config.ts` through `solidStart()`.
+Configuration moved from `app.config.ts` to `vite.config.ts`. The `solidStart()` plugin configures the application, while a deployment Vite plugin configures the server runtime and deployment target.
If you are upgrading an existing app, start with the [migration guide](/solid-start/v2/migrating-from-v1).
diff --git a/src/routes/solid-start/v2/(1)advanced/(0)middleware.mdx b/src/routes/solid-start/v2/(1)advanced/(0)middleware.mdx
new file mode 100644
index 000000000..34b475990
--- /dev/null
+++ b/src/routes/solid-start/v2/(1)advanced/(0)middleware.mdx
@@ -0,0 +1,155 @@
+---
+title: Middleware
+use_cases: >-
+ request interception, header management, global data sharing, request
+ preprocessing, logging, redirects
+tags:
+ - middleware
+ - headers
+ - interceptors
+ - logging
+ - preprocessing
+ - locals
+version: "2.0"
+description: >-
+ Compose H3 v2 middleware for authentication, logging, headers, and
+ request-scoped data in SolidStart.
+---
+
+Middleware runs around SolidStart's request handler. It is useful for logging, redirects, request preprocessing, response headers, and initializing request-scoped data.
+
+Do not rely on middleware alone for authorization. Client-side navigation can reuse data and server functions independently of a page request, so authorization must also be enforced close to each protected query, action, or API route.
+
+## Configure middleware
+
+Create a middleware module and pass its path to `solidStart()`.
+
+```ts title="src/middleware/index.ts"
+import { createMiddleware } from "@solidjs/start/middleware";
+
+export default createMiddleware([
+ async (event, next) => {
+ console.log("Request received:", event.req.url);
+ const startedAt = Date.now();
+
+ const response = await next();
+
+ console.log(`Request took ${Date.now() - startedAt}ms`);
+ return response;
+ },
+]);
+```
+
+```tsx title="vite.config.ts" {7}
+import { nitro } from "nitro/vite";
+import { defineConfig } from "vite";
+import { solidStart } from "@solidjs/start/config";
+
+export default defineConfig({
+ plugins: [solidStart({ middleware: "./src/middleware/index.ts" }), nitro()],
+});
+```
+
+Each entry is an [H3 middleware](https://h3.dev/guide/basics/middleware). Code before `await next()` runs before the downstream handler. Code after it runs as the response unwinds.
+
+## Request-scoped locals
+
+SolidStart decorates configured middleware with its request context. Use `getRequestEvent()` to read or update `event.locals` for later server code.
+
+```ts title="src/middleware/index.ts"
+import { createMiddleware } from "@solidjs/start/middleware";
+import { getRequestEvent } from "solid-js/web";
+
+export default createMiddleware([
+ async (_event, next) => {
+ const requestEvent = getRequestEvent();
+ if (requestEvent) {
+ requestEvent.locals.requestId = crypto.randomUUID();
+ }
+ return next();
+ },
+]);
+```
+
+Augment `App.RequestEventLocals` to type custom fields. See [Request events](/solid-start/v2/advanced/request-events#locals).
+
+## Headers and cookies
+
+H3 v2 uses Web standard `Request`, `Response`, and `Headers` objects. You can access them through the H3 event or use SolidStart's context-aware HTTP helpers.
+
+```ts title="src/middleware/index.ts"
+import { getCookie, setCookie } from "@solidjs/start/http";
+import { createMiddleware } from "@solidjs/start/middleware";
+
+export default createMiddleware([
+ async (event, next) => {
+ const theme = getCookie("theme") ?? "system";
+ setCookie("theme", theme, {
+ httpOnly: true,
+ secure: true,
+ sameSite: "lax",
+ });
+
+ const response = await next();
+ event.res.headers.set("x-theme", theme);
+ return response;
+ },
+]);
+```
+
+`@solidjs/start/http` and `@solidjs/start/middleware` are server-only entrypoints. Importing them from client-reachable code causes a clear development or build error.
+
+## Short-circuit the request
+
+Return a `Response` before calling `next()` to stop the chain.
+
+```ts
+import { createMiddleware } from "@solidjs/start/middleware";
+
+export default createMiddleware([
+ (event, next) => {
+ if (!event.req.headers.get("authorization")) {
+ return new Response("Unauthorized", { status: 401 });
+ }
+ return next();
+ },
+]);
+```
+
+Redirect responses from Solid Router work the same way:
+
+```ts
+import { redirect } from "@solidjs/router";
+import { createMiddleware } from "@solidjs/start/middleware";
+
+export default createMiddleware([
+ (event, next) => {
+ if (new URL(event.req.url).pathname === "/login") {
+ return redirect("/auth/login", 301);
+ }
+ return next();
+ },
+]);
+```
+
+## Middleware order
+
+Middleware uses an onion model. Before-`next()` logic runs in declaration order; after-`next()` logic runs in reverse order.
+
+The v1 object form with `onRequest` and `onBeforeResponse` remains available for migration but is deprecated. In `2.0.0-rc.1`, deprecated `onBeforeResponse` arrays run in their declared order. Remove any manual reversal added as a workaround for earlier prereleases.
+
+## Custom H3 handlers
+
+The experimental `decorateHandler` and `decorateMiddleware` exports from `@solidjs/start/server` provide Solid's request context to custom H3 code that runs outside the configured middleware chain.
+
+```ts
+import { decorateHandler } from "@solidjs/start/server";
+import { defineHandler } from "nitro";
+
+export default defineHandler(
+ decorateHandler(() => {
+ // getRequestEvent() is available here
+ return { ok: true };
+ })
+);
+```
diff --git a/src/routes/solid-start/v2/(1)advanced/(1)session.mdx b/src/routes/solid-start/v2/(1)advanced/(1)session.mdx
new file mode 100644
index 000000000..a0ce18f57
--- /dev/null
+++ b/src/routes/solid-start/v2/(1)advanced/(1)session.mdx
@@ -0,0 +1,87 @@
+---
+title: Sessions
+use_cases: >-
+ user sessions, authentication state, preferences storage, stateful
+ interactions, login persistence
+tags:
+ - sessions
+ - cookies
+ - authentication
+ - state
+ - storage
+ - persistence
+version: "2.0"
+description: >-
+ Manage encrypted cookie sessions with the SolidStart HTTP helpers.
+---
+
+Sessions let the server associate state with multiple requests from the same browser. SolidStart exposes H3 v2's encrypted cookie-session helpers through `@solidjs/start/http`.
+
+Session helpers are server-only. Use them from server functions, API routes, middleware, or other server-only modules.
+
+## Create a session helper
+
+`useSession` reads the current session and returns methods for updating or clearing it.
+
+```ts title="src/lib/session.ts"
+import { useSession } from "@solidjs/start/http";
+
+type SessionData = {
+ userId?: string;
+ theme?: "light" | "dark";
+};
+
+export function useAppSession() {
+ "use server";
+
+ return useSession({
+ name: "app-session",
+ password: process.env.SESSION_SECRET as string,
+ cookie: {
+ httpOnly: true,
+ secure: process.env.NODE_ENV === "production",
+ sameSite: "lax",
+ },
+ });
+}
+```
+
+Use a secret of at least 32 characters and store it in a private environment variable. Generate one with:
+
+```sh frame="none"
+openssl rand -base64 32
+```
+
+## Read session data
+
+```ts
+export async function getCurrentUserId() {
+ "use server";
+ const session = await useAppSession();
+ return session.data.userId ?? null;
+}
+```
+
+## Update session data
+
+```ts
+export async function setTheme(theme: "light" | "dark") {
+ "use server";
+ const session = await useAppSession();
+ await session.update({ theme });
+}
+```
+
+## Clear a session
+
+```ts
+export async function logout() {
+ "use server";
+ const session = await useAppSession();
+ await session.clear();
+}
+```
+
+In addition to `useSession`, `@solidjs/start/http` exports `getSession`, `updateSession`, `clearSession`, `sealSession`, and `unsealSession` for lower-level workflows.
+
+Cookie sessions should contain small, non-sensitive identifiers and preferences. For revocation, device management, or larger data, store the session record in a database and keep only its opaque ID in the cookie.
diff --git a/src/routes/solid-start/v2/(1)advanced/(2)request-events.mdx b/src/routes/solid-start/v2/(1)advanced/(2)request-events.mdx
new file mode 100644
index 000000000..39e9cc755
--- /dev/null
+++ b/src/routes/solid-start/v2/(1)advanced/(2)request-events.mdx
@@ -0,0 +1,56 @@
+---
+title: Request events
+use_cases: >-
+ server context access, local data storage, request handling, server functions,
+ event access
+tags:
+ - events
+ - server
+ - context
+ - locals
+ - requests
+ - functions
+version: "2.0"
+description: >-
+ Access request events, typed locals, and the native H3 v2 event in SolidStart.
+---
+
+Call [`getRequestEvent`](/reference/server-utilities/get-request-event) from `solid-js/web` to access the current request in server-rendering, API, middleware, query, and action code.
+
+```tsx
+import { getRequestEvent } from "solid-js/web";
+
+const event = getRequestEvent();
+const request = event?.request;
+```
+
+`getRequestEvent()` returns `undefined` outside a request context.
+
+## Locals
+
+`event.locals` is request-scoped storage shared by SolidStart middleware and server code. Add your fields to the global `App.RequestEventLocals` interface:
+
+```tsx title="src/env.d.ts"
+declare namespace App {
+ interface RequestEventLocals {
+ user?: { id: string };
+ requestId: string;
+ }
+}
+```
+
+The `@solidjs/start/env` type entry provides the base namespace and should be included in `tsconfig.json`.
+
+```json title="tsconfig.json"
+{
+ "compilerOptions": {
+ "types": ["@solidjs/start/env"]
+ }
+}
+```
+
+## Native event
+
+`event.nativeEvent` is the underlying H3 v2 event. It exposes Web standard request and response objects as `event.nativeEvent.req` and `event.nativeEvent.res`.
+
+Most application code does not need the native event. Prefer `event.request`, `event.response`, or a helper from `@solidjs/start/http`. The HTTP entrypoint is server-only, so import it only from server code or inside a function marked with `"use server"`.
diff --git a/src/routes/solid-start/v2/(1)advanced/(3)return-responses.mdx b/src/routes/solid-start/v2/(1)advanced/(3)return-responses.mdx
new file mode 100644
index 000000000..adaf4b94c
--- /dev/null
+++ b/src/routes/solid-start/v2/(1)advanced/(3)return-responses.mdx
@@ -0,0 +1,62 @@
+---
+title: Returning responses
+use_cases: >-
+ server function responses, error handling, response types, api responses,
+ typescript typing
+tags:
+ - responses
+ - server
+ - functions
+ - typescript
+ - errors
+ - api
+version: "2.0"
+description: >-
+ Return typed Response objects from server functions. Handle redirects,
+ reloads, and JSON responses with proper TypeScript support.
+---
+
+In SolidStart, it is possible to return a Response object from a server function.
+[`solid-router`](/solid-router) knows how to handle certain responses with its [`query`](/solid-router/reference/data-apis/query) and [`action`](/solid-router/reference/data-apis/action) APIs.
+For TypeScript, when returning a response using `solid-router`'s `redirect`, `reload`, or `json` helpers, they will not impact the return value of the server function.
+
+While we suggest depending on the type of the function to handle errors differently, you can always return or throw a response.
+
+## Examples
+
+In the following example, the `hello` function will return a value of type `Promise<{ hello: string }>`:
+
+```tsx
+import { json } from "@solidjs/router";
+import { GET } from "@solidjs/start";
+
+const hello = GET(async (name: string) => {
+ "use server";
+ return json(
+ { hello: new Promise((r) => setTimeout(() => r(name), 1000)) },
+ { headers: { "cache-control": "max-age=60" } }
+ );
+});
+```
+
+However, in this example, since `redirect` and `reload` return `never` as their type, `getUser` can only return a value of type `Promise`:
+
+```tsx { 4, 10, 14}
+export async function getUser() {
+ "use server";
+
+ const session = await getSession();
+ const userId = session.data.userId;
+ if (userId === undefined) return redirect("/login");
+
+ try {
+ const user: User = await db.user.findUnique({ where: { id: userId } });
+ // throwing can be awkward.
+ if (!user) return redirect("/login");
+ return user;
+ } catch {
+ // do stuff
+ throw redirect("/login");
+ }
+}
+```
diff --git a/src/routes/solid-start/v2/(1)advanced/(4)serialization.mdx b/src/routes/solid-start/v2/(1)advanced/(4)serialization.mdx
index 1bca99001..07d59a1df 100644
--- a/src/routes/solid-start/v2/(1)advanced/(4)serialization.mdx
+++ b/src/routes/solid-start/v2/(1)advanced/(4)serialization.mdx
@@ -1,7 +1,8 @@
---
title: Serialization
use_cases: >-
- server function payloads, data transfer, csp, security, performance
+ server function payloads, data transfer, custom types, seroval plugins, csp,
+ security, performance
tags:
- serialization
- server-functions
@@ -40,6 +41,57 @@ export default defineConfig({
If your app enforces a Content Security Policy, keep `json`.
+## Custom types
+
+Use a custom Seroval plugin when a server function needs to accept or return a value that Seroval does not support, such as a database identifier, decimal type, or another custom class.
+
+Set `serialization.plugins` to a module whose default export is an array of plugins:
+
+```tsx title="vite.config.ts"
+import { defineConfig } from "vite";
+import { solidStart } from "@solidjs/start/config";
+
+export default defineConfig({
+ plugins: [
+ solidStart({
+ serialization: {
+ plugins: "src/seroval-plugins.ts",
+ },
+ }),
+ ],
+});
+```
+
+Create plugins with the API exported by `@solidjs/start/serialization`. The entrypoint exports `createPlugin`, `OpaqueReference`, and the related plugin types. Importing from it keeps the plugin on the same Seroval version that SolidStart uses.
+
+```ts title="src/seroval-plugins.ts"
+import { createPlugin } from "@solidjs/start/serialization";
+import { Money } from "./lib/money";
+
+const moneyPlugin = createPlugin({
+ tag: "app/Money",
+ test: (value) => value instanceof Money,
+ parse: {
+ sync: (value, ctx) => ({ cents: ctx.parse(value.cents) }),
+ async: async (value, ctx) => ({
+ cents: await ctx.parse(value.cents),
+ }),
+ stream: (value, ctx) => ({ cents: ctx.parse(value.cents) }),
+ },
+ serialize: (node, ctx) =>
+ `new globalThis.Money(${ctx.serialize(node.cents)})`,
+ deserialize: (node, ctx) => new Money(ctx.deserialize(node.cents) as number),
+});
+
+export default [moneyPlugin];
+```
+
+SolidStart bundles the plugin module into both the client and server builds, so it must not import server-only code. Built-in SolidStart plugins run before custom plugins.
+
+Custom plugins apply to server function and action payloads. They do not affect the hydration payload produced by `solid-js/web`.
+
+With the default `json` mode, `deserialize` rebuilds the value. If you use `js` mode, the code returned by `serialize` can only refer to globals available in the client. In the example above, `Money` must be assigned to `globalThis.Money` before deserialization.
+
## Server function payloads
SolidStart applies extra handling for certain payload types so file uploads and binary data can flow without being serialized by Seroval. This applies to both server function arguments and return values. SolidStart bypasses Seroval for:
diff --git a/src/routes/solid-start/v2/(1)advanced/(5)auth.mdx b/src/routes/solid-start/v2/(1)advanced/(5)auth.mdx
new file mode 100644
index 000000000..b711a3ced
--- /dev/null
+++ b/src/routes/solid-start/v2/(1)advanced/(5)auth.mdx
@@ -0,0 +1,61 @@
+---
+title: Auth
+use_cases: >-
+ user authentication, protected routes, authorization checks, secure data
+ access, login systems
+tags:
+ - authentication
+ - authorization
+ - security
+ - protected
+ - login
+ - users
+version: "2.0"
+description: >-
+ Implement authentication and protected routes in SolidStart. Secure sensitive
+ resources and handle user authorization properly.
+---
+
+Server functions can be used to protect sensitive resources like user data.
+
+```tsx
+"use server";
+
+async function getPrivatePosts() {
+ const user = await getUser();
+ if (!user) {
+ return null; // or throw an error
+ }
+
+ return db.getPosts({ userId: user.id, private: true });
+}
+```
+
+The `getUser` function can be [implemented using sessions](/solid-start/v2/advanced/session).
+
+## Protected Routes
+
+Routes can be protected by checking the user or session object during data fetching.
+This example uses [Solid Router](/solid-router).
+
+```tsx
+const getPrivatePosts = query(async function () {
+ "use server";
+ const user = await getUser();
+ if (!user) {
+ throw redirect("/login");
+ }
+
+ return db.getPosts({ userId: user.id, private: true });
+});
+
+export default function Page() {
+ const posts = createAsync(() => getPrivatePosts(), { deferStream: true });
+}
+```
+
+Once the user hits this route, the router will attempt to fetch `getPrivatePosts` data.
+If the user is not signed in, `getPrivatePosts` will throw and the router will redirect to the login page.
+
+To prevent errors when opening the page directly, set `deferStream: true`.
+This would ensure `getPrivatePosts` resolves before the page loads since server-side redirects cannot occur after streaming has started.
diff --git a/src/routes/solid-start/v2/(1)advanced/(6)websocket.mdx b/src/routes/solid-start/v2/(1)advanced/(6)websocket.mdx
new file mode 100644
index 000000000..bcfebcf15
--- /dev/null
+++ b/src/routes/solid-start/v2/(1)advanced/(6)websocket.mdx
@@ -0,0 +1,72 @@
+---
+title: WebSocket endpoint
+use_cases: >-
+ real-time updates, chat applications, live notifications, multiplayer games,
+ collaborative editing, streaming data
+tags:
+ - websocket
+ - real-time
+ - streaming
+ - server
+ - events
+version: "2.0"
+description: >-
+ Add a Nitro v3 WebSocket endpoint to a SolidStart application.
+---
+
+SolidStart v2 uses Nitro v3's cross-platform WebSocket support. Enable the feature in Nitro's Vite configuration and define the endpoint as a Nitro server route.
+
+## Enable WebSockets
+
+```tsx title="vite.config.ts"
+import { nitro } from "nitro/vite";
+import { defineConfig } from "vite";
+import { solidStart } from "@solidjs/start/config";
+
+export default defineConfig({
+ plugins: [solidStart(), nitro()],
+ nitro: {
+ serverDir: "./server",
+ features: {
+ websocket: true,
+ },
+ },
+});
+```
+
+## Create an endpoint
+
+Files in `server/routes` use Nitro's file-based server routing. This example handles connections at `/ws`.
+
+```ts title="server/routes/ws.ts"
+import { defineWebSocketHandler } from "nitro";
+
+export default defineWebSocketHandler({
+ open(peer) {
+ console.log("open", peer.id);
+ peer.send("Connected");
+ },
+ message(peer, message) {
+ console.log("message", peer.id, message.text());
+ peer.send(message.text());
+ },
+ close(peer, details) {
+ console.log("close", peer.id, details.code, details.reason);
+ },
+ error(peer, error) {
+ console.error("websocket error", peer.id, error);
+ },
+});
+```
+
+Connect with the browser WebSocket API:
+
+```ts
+const protocol = location.protocol === "https:" ? "wss:" : "ws:";
+const socket = new WebSocket(`${protocol}//${location.host}/ws`);
+
+socket.addEventListener("open", () => socket.send("Hello"));
+socket.addEventListener("message", (event) => console.log(event.data));
+```
+
+Nitro also supports upgrade hooks, peer context, topics, namespaces, and pub/sub. See the [Nitro WebSocket guide](https://nitro.build/docs/websocket).
diff --git a/src/routes/solid-start/v2/(1)getting-started.mdx b/src/routes/solid-start/v2/(1)getting-started.mdx
index a912b49a0..14ca5604d 100644
--- a/src/routes/solid-start/v2/(1)getting-started.mdx
+++ b/src/routes/solid-start/v2/(1)getting-started.mdx
@@ -16,7 +16,7 @@ description: >-
---
The easiest way to start a new SolidStart project is with `create-solid`.
-It can scaffold a new app from the SolidStart template or from one of the official examples.
+SolidStart v2 requires Node.js 24 or newer.
## Create a project
@@ -42,14 +42,15 @@ dev
## Configuration
-Configuration lives in `vite.config.ts`, where the `solidStart()` plugin from `@solidjs/start/config` does the work.
+Configuration lives in `vite.config.ts`. SolidStart configures the application and Nitro v3 supplies the server and deployment integration.
```tsx title="vite.config.ts"
import { defineConfig } from "vite";
+import { nitro } from "nitro/vite";
import { solidStart } from "@solidjs/start/config";
export default defineConfig({
- plugins: [solidStart()],
+ plugins: [solidStart(), nitro()],
});
```
@@ -57,13 +58,26 @@ If your app already has middleware, `solidStart()` also accepts a `middleware` o
```tsx title="vite.config.ts"
import { defineConfig } from "vite";
+import { nitro } from "nitro/vite";
import { solidStart } from "@solidjs/start/config";
export default defineConfig({
- plugins: [solidStart({ middleware: "./src/middleware/index.ts" })],
+ plugins: [solidStart({ middleware: "./src/middleware/index.ts" }), nitro()],
});
```
+Use the top-level `nitro` property for Nitro options such as deployment presets, prerendering, tasks, and WebSockets.
+
+## Development toolbar
+
+During development, SolidStart adds a toolbar for inspecting application errors and server function calls. The toolbar is not included in production builds.
+
+To hide it during development, set `devOverlay` to `false`:
+
+```tsx title="vite.config.ts"
+solidStart({ devOverlay: false });
+```
+
## Start adding routes
The filesystem router reads files from your routes directory and turns them into UI routes or API routes.
diff --git a/src/routes/solid-start/v2/(2)guides/(0)security.mdx b/src/routes/solid-start/v2/(2)guides/(0)security.mdx
new file mode 100644
index 000000000..88feed732
--- /dev/null
+++ b/src/routes/solid-start/v2/(2)guides/(0)security.mdx
@@ -0,0 +1,220 @@
+---
+title: Security
+use_cases: >-
+ production apps, user input handling, authentication, public apis, preventing
+ attacks, secure deployments, compliance
+tags:
+ - security
+ - xss
+ - csrf
+ - cors
+ - csp
+ - middleware
+ - protection
+version: "2.0"
+description: >-
+ Secure your SolidStart apps against XSS, CSRF attacks. Configure CSP headers,
+ CORS policies, and implement security best practices.
+---
+
+## XSS (Cross Site Scripting)
+
+Solid automatically escapes values passed to JSX expressions to reduce the risk of XSS attacks.
+However, this protection does not apply when using [`innerHTML`](/reference/jsx-attributes/innerhtml).
+
+To protect your application from XSS attacks:
+
+- Set a [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP).
+- Validate and sanitize user inputs, especially form inputs on the server and client.
+- Avoid using `innerHTML` when possible.
+ If necessary, make sure to sanitize user-supplied data with libraries such as [DOMPurify](https://github.com/cure53/DOMPurify).
+- Sanitize attributes containing user-supplied data within `` elements.
+ This includes both the attributes of the `` element itself and its children.
+- When URLs are provided or constructed via user input validate its `origin` and `protocol` (to avoid evaluating code via `javascript:` URLs) using the [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) API.
+
+It is highly recommended to read the [Cross Site Scripting Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html) for further guidance.
+
+## Content Security Policy (CSP)
+
+To configure the `Content-Security-Policy` HTTP header, a [middleware](/solid-start/v2/advanced/middleware) can be used.
+
+SolidStart v2 defaults to JSON serialization, which avoids an `unsafe-eval` requirement. Keep that default for a strict CSP. See [`solidStart` serialization](/solid-start/v2/reference/config/solid-start#serialization).
+
+### With nonce (recommended)
+
+If you want to use a [strict CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP#strict_csp) with nonces:
+
+1. Create middleware that generates a nonce and configures the CSP header before calling `next()`.
+2. Create a nonce using a cryptographic random value generator, such as the [`randomBytes`](https://nodejs.org/api/crypto.html#cryptorandombytessize-callback) function from the `crypto` module.
+3. Store the nonce in the [`locals`](/solid-start/v2/advanced/middleware#locals) object.
+4. Configure SolidStart to use the nonce in your [`entry-server.tsx`](/solid-start/v2/reference/entrypoints/entry-server) file.
+
+```tsx tab title="Middleware"
+import { createMiddleware } from "@solidjs/start/middleware";
+import { randomBytes } from "node:crypto";
+import { getRequestEvent } from "solid-js/web";
+
+export default createMiddleware([
+ (event, next) => {
+ const nonce = randomBytes(16).toString("base64");
+ const requestEvent = getRequestEvent();
+ if (requestEvent) requestEvent.locals.nonce = nonce;
+
+ const csp = `
+ default-src 'self';
+ script-src 'nonce-${nonce}' 'strict-dynamic';
+ object-src 'none';
+ base-uri 'none';
+ frame-ancestors 'none';
+ form-action 'self';
+ `.replace(/\s+/g, " ");
+
+ event.res.headers.set("Content-Security-Policy", csp);
+ return next();
+ },
+]);
+```
+
+```tsx tab title="entry-server.tsx" {7}
+// src/entry-server.tsx
+// @refresh reload
+import { createHandler, StartServer } from "@solidjs/start/server";
+
+export default createHandler(
+ () => ,
+ (event) => ({ nonce: event.locals.nonce })
+);
+```
+
+### Without nonce
+
+To configure CSP without a nonce, set the header after the downstream handler returns:
+
+```tsx
+import { createMiddleware } from "@solidjs/start/middleware";
+
+export default createMiddleware([
+ async (event, next) => {
+ const response = await next();
+ const csp = `
+ default-src 'self';
+ font-src 'self' ;
+ object-src 'none';
+ base-uri 'none';
+ frame-ancestors 'none';
+ form-action 'self';
+ `.replace(/\s+/g, " ");
+
+ event.res.headers.set("Content-Security-Policy", csp);
+ return response;
+ },
+]);
+```
+
+## CORS (Cross-Origin Resource Sharing)
+
+When other applications need access to API endpoints, a middleware that configures the CORS headers is needed:
+
+```tsx
+import { createMiddleware } from "@solidjs/start/middleware";
+
+const TRUSTED_ORIGINS = ["https://my-app.com", "https://another-app.com"];
+
+export default createMiddleware([
+ async (event, next) => {
+ const origin = event.req.headers.get("Origin");
+ const requestUrl = new URL(event.req.url);
+ const isApiRequest = requestUrl && requestUrl.pathname.startsWith("/api");
+
+ if (isApiRequest && origin && TRUSTED_ORIGINS.includes(origin)) {
+ if (
+ event.req.method === "OPTIONS" &&
+ event.req.headers.get("Access-Control-Request-Method")
+ ) {
+ return new Response(null, {
+ headers: {
+ "Access-Control-Allow-Origin": origin,
+ "Access-Control-Allow-Methods": "OPTIONS, POST, PUT, PATCH, DELETE",
+ "Access-Control-Allow-Headers": "Authorization, Content-Type",
+ Vary: "Origin, Access-Control-Request-Method",
+ },
+ });
+ }
+
+ event.res.headers.set("Access-Control-Allow-Origin", origin);
+ }
+
+ event.res.headers.append("Vary", "Origin, Access-Control-Request-Method");
+ return next();
+ },
+]);
+```
+
+## CSRF (Cross-Site Request Forgery)
+
+To prevent basic CSRF attacks, a middleware can be used to block untrusted requests:
+
+```tsx
+import { createMiddleware } from "@solidjs/start/middleware";
+
+const SAFE_METHODS = ["GET", "HEAD", "OPTIONS", "TRACE"];
+const TRUSTED_ORIGINS = ["https://another-app.com"];
+
+export default createMiddleware([
+ (event, next) => {
+ const request = event.req;
+
+ if (!SAFE_METHODS.includes(request.method)) {
+ const requestUrl = new URL(request.url);
+ const origin = request.headers.get("Origin");
+
+ // If we have an Origin header, check it against our allowlist.
+ if (origin) {
+ const parsedOrigin = new URL(origin);
+
+ if (
+ parsedOrigin.origin !== requestUrl.origin &&
+ !TRUSTED_ORIGINS.includes(parsedOrigin.host)
+ ) {
+ return Response.json({ error: "origin invalid" }, { status: 403 });
+ }
+ }
+
+ // If we are serving via TLS and have no Origin header, prevent against
+ // CSRF via HTTP man-in-the-middle attacks by enforcing strict Referer
+ // origin checks.
+ if (!origin && requestUrl.protocol === "https:") {
+ const referer = request.headers.get("Referer");
+
+ if (!referer) {
+ return Response.json(
+ { error: "referer not supplied" },
+ { status: 403 }
+ );
+ }
+
+ const parsedReferer = new URL(referer);
+
+ if (parsedReferer.protocol !== "https:") {
+ return Response.json({ error: "referer invalid" }, { status: 403 });
+ }
+
+ if (
+ parsedReferer.host !== requestUrl.host &&
+ !TRUSTED_ORIGINS.includes(parsedReferer.host)
+ ) {
+ return Response.json({ error: "referer invalid" }, { status: 403 });
+ }
+ }
+ }
+
+ return next();
+ },
+]);
+```
+
+This example demonstrates a basic CSRF protection that verifies the `Origin` and `Referer` headers, blocking requests from untrusted origins.
+**Please note both of these headers can be forged.**
+Additionally, consider implementing a more robust CSRF protection mechanism, such as the [Double-Submit Cookie Pattern](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#alternative-using-a-double-submit-cookie-pattern).
+
+For further guidance, you can look at the [Cross-Site Request Forgery Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html).
diff --git a/src/routes/solid-start/v2/(2)guides/(1)data-fetching.mdx b/src/routes/solid-start/v2/(2)guides/(1)data-fetching.mdx
new file mode 100644
index 000000000..43cd3f981
--- /dev/null
+++ b/src/routes/solid-start/v2/(2)guides/(1)data-fetching.mdx
@@ -0,0 +1,396 @@
+---
+title: Data fetching
+use_cases: >-
+ api calls, database queries, loading states, error handling, preloading data,
+ client fetching, orm integration
+tags:
+ - fetch
+ - data
+ - api
+ - async
+ - loading
+ - query
+ - database
+version: "2.0"
+description: >-
+ Master data fetching in SolidStart with practical examples. Handle loading
+ states, errors, preloading, and database queries.
+---
+
+This guide provides practical examples of common data-fetching tasks in SolidStart.
+
+Here's an example showing how to create a [`query`](/solid-router/reference/data-apis/query) and access its data with the [`createAsync` primitive](/solid-router/reference/data-apis/create-async):
+
+```tsx tab title="TypeScript"
+// src/routes/index.tsx
+import { For } from "solid-js";
+import { query, createAsync } from "@solidjs/router";
+
+const getPosts = query(async () => {
+ const posts = await fetch("https://my-api.com/posts");
+ return await posts.json();
+}, "posts");
+
+export default function Page() {
+ const posts = createAsync(() => getPosts());
+ return (
+
+ {(post) => {post.title} }
+
+ );
+}
+```
+
+```jsx tab title="JavaScript"
+// src/routes/index.jsx
+import { For } from "solid-js";
+import { query, createAsync } from "@solidjs/router";
+
+const getPosts = query(async () => {
+ const posts = await fetch("https://my-api.com/posts");
+ return await posts.json();
+}, "posts");
+
+export default function Page() {
+ const posts = createAsync(() => getPosts());
+ return (
+
+ {(post) => {post.title} }
+
+ );
+}
+```
+
+## Showing loading UI
+
+To show a loading UI during data fetching:
+
+1. Import [`Suspense`](/reference/components/suspense) from `solid-js`.
+2. Wrap your data rendering in ``, and use the `fallback` prop to show a component during data fetching.
+
+```tsx tab title="TypeScript" {14} {16}
+// src/routes/index.tsx
+import { Suspense, For } from "solid-js";
+import { query, createAsync } from "@solidjs/router";
+
+const getPosts = query(async () => {
+ const posts = await fetch("https://my-api.com/posts");
+ return await posts.json();
+}, "posts");
+
+export default function Page() {
+ const posts = createAsync(() => getPosts());
+ return (
+
+ Loading...}>
+ {(post) => {post.title} }
+
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {14} {16}
+// src/routes/index.jsx
+import { Suspense, For } from "solid-js";
+import { query, createAsync } from "@solidjs/router";
+
+const getPosts = query(async () => {
+ const posts = await fetch("https://my-api.com/posts");
+ return await posts.json();
+}, "posts");
+
+export default function Page() {
+ const posts = createAsync(() => getPosts());
+ return (
+
+ Loading...}>
+ {(post) => {post.title} }
+
+
+ );
+}
+```
+
+## Handling errors
+
+To show a fallback UI if the data fetching fails:
+
+1. Import [`ErrorBoundary`](/reference/components/error-boundary) from `solid-js`.
+2. Wrap the data rendering in ``, and use the `fallback` prop to show a component if an error occurs.
+
+```tsx tab title="TypeScript" {14} {18}
+// src/routes/index.tsx
+import { ErrorBoundary, Suspense, For } from "solid-js";
+import { query, createAsync } from "@solidjs/router";
+
+const getPosts = query(async () => {
+ const posts = await fetch("https://my-api.com/posts");
+ return await posts.json();
+}, "posts");
+
+export default function Page() {
+ const posts = createAsync(() => getPosts());
+ return (
+
+ Something went wrong!}>
+ Loading...}>
+ {(post) => {post.title} }
+
+
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {14} {18}
+// src/routes/index.jsx
+import { ErrorBoundary, Suspense, For } from "solid-js";
+import { query, createAsync } from "@solidjs/router";
+
+const getPosts = query(async () => {
+ const posts = await fetch("https://my-api.com/posts");
+ return await posts.json();
+}, "posts");
+
+export default function Page() {
+ const posts = createAsync(() => getPosts());
+ return (
+
+ Something went wrong!}>
+ Loading...}>
+ {(post) => {post.title} }
+
+
+
+ );
+}
+```
+
+## Preloading data
+
+To preload data before a route renders:
+
+1. Export a `route` object with a [`preload`](/solid-router/reference/preload-functions/preload) function.
+2. Run your query inside the `preload` function.
+3. Use the query as usual in your component.
+
+```tsx tab title="TypeScript" {10-12}
+// src/routes/index.tsx
+import { ErrorBoundary } from "solid-js";
+import { query, createAsync, type RouteDefinition } from "@solidjs/router";
+
+const getPosts = query(async () => {
+ const posts = await fetch("https://my-api.com/posts");
+ return await posts.json();
+}, "posts");
+
+export const route = {
+ preload: () => getPosts(),
+} satisfies RouteDefinition;
+
+export default function Page() {
+ const post = createAsync(() => getPosts());
+ return (
+
+ Something went wrong!
}>
+ {post().title}
+
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {10-12}
+// src/routes/index.jsx
+import { ErrorBoundary } from "solid-js";
+import { query, createAsync } from "@solidjs/router";
+
+const getPosts = query(async () => {
+ const posts = await fetch("https://my-api.com/posts");
+ return await posts.json();
+}, "posts");
+
+export const route = {
+ preload: () => getPosts(),
+};
+
+export default function Page() {
+ const post = createAsync(() => getPosts());
+ return (
+
+ Something went wrong!
}>
+ {post().title}
+
+
+ );
+}
+```
+
+## Passing parameters to queries
+
+When creating a query that accepts parameters, define your query function to take any number of parameters:
+
+```tsx tab title="TypeScript" {5} {11} {16}
+// src/routes/posts/[id]/index.tsx
+import { ErrorBoundary } from "solid-js";
+import { query, createAsync, type RouteDefinition } from "@solidjs/router";
+
+const getPost = query(async (id: string) => {
+ const post = await fetch(`https://my-api.com/posts/${id}`);
+ return await post.json();
+}, "post");
+
+export const route = {
+ preload: ({ params }) => getPost(params.id),
+} satisfies RouteDefinition;
+
+export default function Page() {
+ const postId = 1;
+ const post = createAsync(() => getPost(postId));
+ return (
+
+ Something went wrong!
}>
+ {post().title}
+
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {5} {11} {16}
+// src/routes/posts/[id]/index.jsx
+import { ErrorBoundary } from "solid-js";
+import { query, createAsync } from "@solidjs/router";
+
+const getPost = query(async (id) => {
+ const post = await fetch(`https://my-api.com/posts/${id}`);
+ return await post.json();
+}, "post");
+
+export const route = {
+ preload: ({ params }) => getPost(params.id),
+};
+
+export default function Page() {
+ const postId = 1;
+ const post = createAsync(() => getPost(postId));
+ return (
+
+ Something went wrong!
}>
+ {post().title}
+
+
+ );
+}
+```
+
+## Using a database or an ORM
+
+To safely interact with your database or ORM in a query, use a [server function](/solid-start/v2/reference/server/use-server):
+
+```tsx tab title="TypeScript" {7-8}
+// src/routes/index.tsx
+import { For, ErrorBoundary } from "solid-js";
+import { query, createAsync, type RouteDefinition } from "@solidjs/router";
+import { db } from "~/lib/db";
+
+const getPosts = query(async () => {
+ "use server";
+ return await db.from("posts").select();
+}, "posts");
+
+export const route = {
+ preload: () => getPosts(),
+} satisfies RouteDefinition;
+
+export default function Page() {
+ const posts = createAsync(() => getPosts());
+ return (
+
+ Something went wrong!}>
+ {(post) => {post.title} }
+
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {7-8}
+// src/routes/index.jsx
+import { For, ErrorBoundary } from "solid-js";
+import { query, createAsync } from "@solidjs/router";
+import { db } from "~/lib/db";
+
+const getPosts = query(async () => {
+ "use server";
+ return await db.from("posts").select();
+}, "posts");
+
+export const route = {
+ preload: () => getPosts(),
+};
+
+export default function Page() {
+ const posts = createAsync(() => getPosts());
+ return (
+
+ Something went wrong!}>
+ {(post) => {post.title} }
+
+
+ );
+}
+```
+
+## Fetching data on the client
+
+To fetch data only on the client, use the [`createResource`](/reference/basic-reactivity/create-resource) primitive:
+
+```tsx tab title="TypeScript" {5-8} {13}
+// src/routes/index.tsx
+import { createResource, ErrorBoundary, Suspense, For } from "solid-js";
+
+export default function Page() {
+ const [posts] = createResource(async () => {
+ const posts = await fetch("https://my-api.com/posts");
+ return await posts.json();
+ });
+ return (
+
+ Something went wrong!}>
+ Loading...}>
+ {(post) => {post.title} }
+
+
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {5-8} {13}
+// src/routes/index.jsx
+import { createResource, ErrorBoundary, Suspense, For } from "solid-js";
+
+export default function Page() {
+ const [posts] = createResource(async () => {
+ const posts = await fetch("https://my-api.com/posts");
+ return await posts.json();
+ });
+ return (
+
+ Something went wrong!}>
+ Loading...}>
+ {(post) => {post.title} }
+
+
+
+ );
+}
+```
+
+See the [`createResource`](/reference/basic-reactivity/create-resource) API reference for more information.
+
+:::note[Advanced Data Handling]
+For advanced features like automatic background re-fetching or infinite queries, you can use [TanStack Query](https://tanstack.com/query/latest/docs/framework/solid/overview).
+:::
diff --git a/src/routes/solid-start/v2/(2)guides/(2)data-mutation.mdx b/src/routes/solid-start/v2/(2)guides/(2)data-mutation.mdx
new file mode 100644
index 000000000..8cb60e2f4
--- /dev/null
+++ b/src/routes/solid-start/v2/(2)guides/(2)data-mutation.mdx
@@ -0,0 +1,557 @@
+---
+title: Data mutation
+use_cases: >-
+ form submission, data updates, crud operations, user input handling, database
+ writes, api posts, validation, optimistic ui
+tags:
+ - forms
+ - actions
+ - mutations
+ - validation
+ - database
+ - api
+ - crud
+version: "2.0"
+description: >-
+ Learn how to handle form submissions, validate data, and perform mutations
+ with SolidStart actions. Complete guide with examples.
+---
+
+This guide provides practical examples of using actions to mutate data in SolidStart.
+
+## Handling form submission
+
+To handle [`
+ );
+}
+```
+
+```jsx tab title="JavaScript" {4-10} {14}
+// src/routes/index.jsx
+import { action } from "@solidjs/router";
+
+const addPost = action(async (formData) => {
+ const title = formData.get("title");
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ return (
+
+ );
+}
+```
+
+## Passing additional arguments
+
+To pass additional arguments to your action, use the `with` method:
+
+```tsx tab title="TypeScript" {4} {15}
+// src/routes/index.tsx
+import { action } from "@solidjs/router";
+
+const addPost = action(async (userId: number, formData: FormData) => {
+ const title = formData.get("title") as string;
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ userId, title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const userId = 1;
+ return (
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {4} {15}
+// src/routes/index.jsx
+import { action } from "@solidjs/router";
+
+const addPost = action(async (userId, formData) => {
+ const title = formData.get("title");
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ userId, title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const userId = 1;
+ return (
+
+ );
+}
+```
+
+## Showing pending UI
+
+To display a pending UI during action execution:
+
+1. Import [`useSubmission`](/solid-router/reference/data-apis/use-submission) from `@solidjs/router`.
+2. Call `useSubmission` with your action, and use the returned `pending` property to display pending UI.
+
+```tsx tab title="TypeScript" {13} {17-19}
+// src/routes/index.tsx
+import { action, useSubmission } from "@solidjs/router";
+
+const addPost = action(async (formData: FormData) => {
+ const title = formData.get("title") as string;
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const submission = useSubmission(addPost);
+ return (
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {13} {17-19}
+// src/routes/index.jsx
+import { action, useSubmission } from "@solidjs/router";
+
+const addPost = action(async (formData) => {
+ const title = formData.get("title");
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const submission = useSubmission(addPost);
+ return (
+
+ );
+}
+```
+
+## Handling errors
+
+To handle errors that occur within an action:
+
+1. Import [`useSubmission`](/solid-router/reference/data-apis/use-submission) from `@solidjs/router`.
+2. Call `useSubmission` with your action, and use the returned `error` property to handle the error.
+
+```tsx tab title="TypeScript" {14} {17-19}
+// src/routes/index.tsx
+import { Show } from "solid-js";
+import { action, useSubmission } from "@solidjs/router";
+
+const addPost = action(async (formData: FormData) => {
+ const title = formData.get("title") as string;
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const submission = useSubmission(addPost);
+ return (
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {14} {17-19}
+// src/routes/index.jsx
+import { Show } from "solid-js";
+import { action, useSubmission } from "@solidjs/router";
+
+const addPost = action(async (formData) => {
+ const title = formData.get("title");
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const submission = useSubmission(addPost);
+ return (
+
+ );
+}
+```
+
+## Validating form fields
+
+To validate form fields in an action:
+
+1. Add validation logic in your action and return validation errors if the data is invalid.
+2. Import [`useSubmission`](/solid-router/reference/data-apis/use-submission) from `@solidjs/router`.
+3. Call `useSubmission` with your action, and use the returned `result` property to handle the errors.
+
+```tsx tab title="TypeScript" {7-11} {19} {23-25}
+// src/routes/index.tsx
+import { Show } from "solid-js";
+import { action, useSubmission } from "@solidjs/router";
+
+const addPost = action(async (formData: FormData) => {
+ const title = formData.get("title") as string;
+ if (!title || title.length < 2) {
+ return {
+ error: "Title must be at least 2 characters",
+ };
+ }
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const submission = useSubmission(addPost);
+ return (
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {7-11} {19} {23-25}
+// src/routes/index.jsx
+import { Show } from "solid-js";
+import { action, useSubmission } from "@solidjs/router";
+
+const addPost = action(async (formData) => {
+ const title = formData.get("title");
+ if (!title || title.length < 2) {
+ return {
+ error: "Title must be at least 2 characters",
+ };
+ }
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const submission = useSubmission(addPost);
+ return (
+
+ );
+}
+```
+
+## Showing optimistic UI
+
+To update the UI before the server responds:
+
+1. Import [`useSubmission`](/solid-router/reference/data-apis/use-submission) from `@solidjs/router`.
+2. Call `useSubmission` with your action, and use the returned `pending` and `input` properties to display optimistic UI.
+
+```tsx tab title="TypeScript" {20} {29-31}
+// src/routes/index.tsx
+import { For, Show } from "solid-js";
+import { action, useSubmission, query, createAsync } from "@solidjs/router";
+
+const getPosts = query(async () => {
+ const posts = await fetch("https://my-api.com/blog");
+ return await posts.json();
+}, "posts");
+
+const addPost = action(async (formData: FormData) => {
+ const title = formData.get("title");
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const posts = createAsync(() => getPosts());
+ const submission = useSubmission(addPost);
+ return (
+
+
+
+ {(post) => {post.title} }
+
+ {submission.input?.[0]?.get("title")?.toString()}
+
+
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {20} {29-31}
+// src/routes/index.jsx
+import { For, Show } from "solid-js";
+import { action, useSubmission, query, createAsync } from "@solidjs/router";
+
+const getPosts = query(async () => {
+ const posts = await fetch("https://my-api.com/blog");
+ return await posts.json();
+}, "posts");
+
+const addPost = action(async (formData) => {
+ const title = formData.get("title");
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const posts = createAsync(() => getPosts());
+ const submission = useSubmission(addPost);
+ return (
+
+
+
+ {(post) => {post.title} }
+
+ {submission.input?.[0]?.get("title")?.toString()}
+
+
+
+ );
+}
+```
+
+:::note[Multiple Submissions]
+If you want to display optimistic UI for multiple concurrent submissions, you can use the [`useSubmissions`](/solid-router/reference/data-apis/use-submissions) primitive.
+:::
+
+## Redirecting
+
+To redirect users to a different route within an action:
+
+1. Import [`redirect`](/solid-router/reference/response-helpers/redirect) from `@solidjs/router`.
+2. Call `redirect` with the route you want to navigate to, and throw its response.
+
+```tsx tab title="TypeScript" {11}
+// src/routes/index.tsx
+import { action, redirect } from "@solidjs/router";
+
+const addPost = action(async (formData: FormData) => {
+ const title = formData.get("title") as string;
+ const response = await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+ const post = await response.json();
+ throw redirect(`/posts/${post.id}`);
+}, "addPost");
+
+export default function Page() {
+ return (
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {11}
+// src/routes/index.jsx
+import { action, redirect } from "@solidjs/router";
+
+const addPost = action(async (formData) => {
+ const title = formData.get("title");
+ const response = await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+ const post = await response.json();
+ throw redirect(`/posts/${post.id}`);
+}, "addPost");
+
+export default function Page() {
+ return (
+
+ );
+}
+```
+
+## Using a database or an ORM
+
+To safely interact with your database or ORM in an action, ensure it's server-only by adding [`"use server"`](/solid-start/v2/reference/server/use-server) as the first line of your action:
+
+```tsx tab title="TypeScript" {6}
+// src/routes/index.tsx
+import { action } from "@solidjs/router";
+import { db } from "~/lib/db";
+
+const addPost = action(async (formData: FormData) => {
+ "use server";
+ const title = formData.get("title") as string;
+ await db.insert("posts").values({ title });
+}, "addPost");
+
+export default function Page() {
+ return (
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {6}
+// src/routes/index.jsx
+import { action } from "@solidjs/router";
+import { db } from "~/lib/db";
+
+const addPost = action(async (formData) => {
+ "use server";
+ const title = formData.get("title");
+ await db.insert("posts").values({ title });
+}, "addPost");
+
+export default function Page() {
+ return (
+
+ );
+}
+```
+
+## Triggering an action programmatically
+
+To programmatically trigger an action:
+
+1. Import [`useAction`](/solid-router/reference/data-apis/use-action) from `@solidjs/router`.
+2. Call `useAction` with your action, and use the returned function to trigger the action.
+
+```tsx tab title="TypeScript" {14} {18}
+// src/routes/index.tsx
+import { createSignal } from "solid-js";
+import { action, useAction } from "@solidjs/router";
+
+const addPost = action(async (title: string) => {
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const [title, setTitle] = createSignal("");
+ const addPostAction = useAction(addPost);
+ return (
+
+ setTitle(e.target.value)} />
+ addPostAction(title())}>Add Post
+
+ );
+}
+```
+
+```jsx tab title="JavaScript" {14} {18}
+// src/routes/index.jsx
+import { createSignal } from "solid-js";
+import { action, useAction } from "@solidjs/router";
+
+const addPost = action(async (title) => {
+ await fetch("https://my-api.com/posts", {
+ method: "POST",
+ body: JSON.stringify({ title }),
+ });
+}, "addPost");
+
+export default function Page() {
+ const [title, setTitle] = createSignal("");
+ const addPostAction = useAction(addPost);
+ return (
+
+ setTitle(e.target.value)} />
+ addPostAction(title())}>Add Post
+
+ );
+}
+```
diff --git a/src/routes/solid-start/v2/(2)guides/(3)service-workers.mdx b/src/routes/solid-start/v2/(2)guides/(3)service-workers.mdx
new file mode 100644
index 000000000..f4eba7bf6
--- /dev/null
+++ b/src/routes/solid-start/v2/(2)guides/(3)service-workers.mdx
@@ -0,0 +1,34 @@
+---
+title: Service workers
+use_cases: >-
+ offline support, pwa, caching, background sync, push notifications,
+ performance optimization
+tags:
+ - service-workers
+ - pwa
+ - offline
+ - caching
+ - performance
+version: "2.0"
+description: >-
+ Register and configure service workers in SolidStart for offline support,
+ caching strategies, and progressive web app features.
+---
+
+To register a service worker:
+
+1. Place your service-worker file in the `public` directory (e.g., `public/sw.js`), making it available at the root URL (`/sw.js`).
+2. Add registration logic to the `entry-client.tsx` file.
+
+```tsx {6-11} title="src/entry-client.tsx"
+// @refresh reload
+import { mount, StartClient } from "@solidjs/start/client";
+
+mount(() => , document.getElementById("app")!);
+
+if ("serviceWorker" in navigator && import.meta.env.PROD) {
+ window.addEventListener("load", () => {
+ navigator.serviceWorker.register("/sw.js");
+ });
+}
+```
diff --git a/src/routes/solid-start/v2/(2)guides/(4)background-tasks.mdx b/src/routes/solid-start/v2/(2)guides/(4)background-tasks.mdx
new file mode 100644
index 000000000..48677c677
--- /dev/null
+++ b/src/routes/solid-start/v2/(2)guides/(4)background-tasks.mdx
@@ -0,0 +1,89 @@
+---
+title: Background tasks
+use_cases: >-
+ background tasks, scheduled jobs, periodic jobs, cron, automation
+tags:
+ - tasks
+ - nitro
+ - cron
+ - scheduling
+ - server
+version: "2.0"
+description: >-
+ Define and schedule background tasks in SolidStart with Nitro v3.
+---
+
+SolidStart v2 can use Nitro v3's experimental Tasks API for on-demand and scheduled background work. Platform support depends on the deployment preset.
+
+## Enable tasks
+
+```tsx title="vite.config.ts"
+import { nitro } from "nitro/vite";
+import { defineConfig } from "vite";
+import { solidStart } from "@solidjs/start/config";
+
+export default defineConfig({
+ plugins: [solidStart(), nitro()],
+ nitro: {
+ serverDir: "./server",
+ experimental: {
+ tasks: true,
+ },
+ },
+});
+```
+
+## Define a task
+
+Files under `server/tasks` are registered automatically. Nested folders become colon-separated task names, so `server/tasks/db/cleanup.ts` is named `db:cleanup`.
+
+```ts title="server/tasks/db/cleanup.ts"
+import { defineTask } from "nitro/task";
+
+export default defineTask({
+ meta: {
+ name: "db:cleanup",
+ description: "Remove expired sessions",
+ },
+ async run({ payload, context }) {
+ const cleanup = deleteExpiredSessions();
+ context.waitUntil?.(cleanup);
+ const deleted = await cleanup;
+
+ return {
+ result: { deleted, requestedBy: payload.requestedBy },
+ };
+ },
+});
+```
+
+## Schedule a task
+
+Map cron expressions to task names in the Nitro configuration.
+
+```tsx title="vite.config.ts"
+export default defineConfig({
+ plugins: [solidStart(), nitro()],
+ nitro: {
+ serverDir: "./server",
+ experimental: { tasks: true },
+ scheduledTasks: {
+ "0 * * * *": "db:cleanup",
+ },
+ },
+});
+```
+
+The `dev`, Node, Bun, and Deno presets run schedules with a cron engine. Cloudflare and Vercel presets integrate with their native scheduling features.
+
+## Run a task during development
+
+With the development server running, invoke a task through Nitro's development endpoint:
+
+```sh frame="none"
+curl http://localhost:5173/_nitro/tasks/db:cleanup
+```
+
+The endpoint can accept query parameters or a JSON body under the `payload` property. Do not expose an equivalent production endpoint without authentication and input validation.
+
+See the [Nitro Tasks guide](https://nitro.build/docs/tasks) for programmatic execution, concurrency behavior, payloads, and platform support.
diff --git a/src/routes/solid-start/v2/(2)migrating-from-v1.mdx b/src/routes/solid-start/v2/(2)migrating-from-v1.mdx
index 2ea44c50f..0c5253fa7 100644
--- a/src/routes/solid-start/v2/(2)migrating-from-v1.mdx
+++ b/src/routes/solid-start/v2/(2)migrating-from-v1.mdx
@@ -14,8 +14,7 @@ description: >-
Migrate your SolidStart project from v1 to v2.
---
-This guide covers the package-level migration changes for SolidStart 2.0.
-It focuses on the parts of the upgrade that already have corresponding v2 docs in this site.
+This guide covers the changes needed to move a SolidStart v1 application from Vinxi and Nitro v2 to SolidStart v2, Vite's Environment API, and Nitro v3.
Some ecosystem packages may still target v1-only APIs.
Audit those dependencies before shipping a production upgrade.
@@ -25,14 +24,38 @@ Audit those dependencies before shipping a production upgrade.
### Update dependencies
```package-install
-@solidjs/start@2.0.0-alpha.3
+@solidjs/start@2.0.0-rc.5 nitro@3 vite@8
```
```package-remove
-vinxi
+vinxi @solidjs/vite-plugin-nitro-2 nitropack
```
-The framework plugin now comes from `@solidjs/start/config`.
+`@solidjs/vite-plugin-nitro-2` was a temporary compatibility layer for using Nitro v2 through Vite. It is deprecated and is not part of the RC setup. Use Nitro v3's own `nitro()` plugin from `nitro/vite`.
+
+SolidStart v2 requires Node.js 24 or newer. Update the `engines` field and your local, CI, and deployment runtimes before installing:
+
+```json title="package.json"
+{
+ "engines": {
+ "node": ">=24"
+ }
+}
+```
+
+Replace the Vinxi scripts with Vite scripts:
+
+```json title="package.json"
+{
+ "scripts": {
+ "dev": "vite dev",
+ "build": "vite build",
+ "preview": "vite preview"
+ }
+}
+```
+
+`vite preview` is for locally checking a production build. Run or deploy Nitro's generated output according to the selected preset in production.
### Move framework configuration into `vite.config.ts`
@@ -41,10 +64,29 @@ Move that setup into a Vite config that calls `solidStart()`.
```tsx title="vite.config.ts"
import { defineConfig } from "vite";
+import { nitro } from "nitro/vite";
import { solidStart } from "@solidjs/start/config";
export default defineConfig({
- plugins: [solidStart()],
+ plugins: [solidStart(), nitro()],
+});
+```
+
+Remove `app.config.ts` after moving its settings. SolidStart options go to `solidStart()`. Options that were nested under v1's `server` property go to the top-level `nitro` property:
+
+```tsx title="vite.config.ts"
+import { nitro } from "nitro/vite";
+import { defineConfig } from "vite";
+import { solidStart } from "@solidjs/start/config";
+
+export default defineConfig({
+ plugins: [solidStart(), nitro()],
+ nitro: {
+ preset: "cloudflare_module",
+ prerender: {
+ routes: ["/", "/about"],
+ },
+ },
});
```
@@ -52,10 +94,11 @@ If your app already has custom middleware, `solidStart()` also exposes a `middle
```tsx title="vite.config.ts"
import { defineConfig } from "vite";
+import { nitro } from "nitro/vite";
import { solidStart } from "@solidjs/start/config";
export default defineConfig({
- plugins: [solidStart({ middleware: "./src/middleware/index.ts" })],
+ plugins: [solidStart({ middleware: "./src/middleware/index.ts" }), nitro()],
});
```
@@ -70,6 +113,8 @@ import { getCookie, setCookie, useSession } from "@solidjs/start/http";
The HTTP entrypoint exposes helpers such as `readBody`, `getQuery`, `getRequestHeader`, `setResponseHeader`, `useSession`, and related cookie/session utilities.
+Nitro v3 uses H3 v2 and Web standard `Request`, `Response`, and `Headers` objects. Code that directly used `event.node`, `event.web`, or H3 v1 response helpers must follow the [Nitro v3 migration guide](https://nitro.build/docs/migration).
+
### Update TypeScript environment types
Environment types ship in `@solidjs/start/env`.
@@ -85,23 +130,45 @@ Make sure your TypeScript config includes it.
### Revisit middleware syntax
-The v2 middleware entrypoint exports `createMiddleware`, and its types now prefer H3 middleware arrays.
-The older `onRequest` and `onBeforeResponse` object form is still present but marked deprecated in the package types.
+The v2 middleware entrypoint exports `createMiddleware`, and its preferred form is an array of H3 v2 middleware.
+The older `onRequest` and `onBeforeResponse` object form still works but is deprecated.
```tsx
import { createMiddleware } from "@solidjs/start/middleware";
export default createMiddleware([
- async (_event, next) => {
- return await next();
+ async (event, next) => {
+ event.context.startedAt = Date.now();
+ const response = await next();
+ console.log(`Request took ${Date.now() - event.context.startedAt}ms`);
+ return response;
},
]);
```
-## Still in the v1 docs
+### Update Nitro v2 APIs
+
+If your app uses Nitro directly, apply these common v3 changes:
-A few topics keep their v1 guidance until the v2 pages land:
+- Replace the `nitropack` package and `nitropack/*` imports with `nitro` and its documented subpath exports.
+- Replace H3 v1 `eventHandler` or `defineEventHandler` with `defineHandler` from `nitro`.
+- Return response bodies, streams, and redirects instead of calling the removed `send*` helpers.
+- Revisit renamed deployment presets, especially Cloudflare, Vercel Edge, Firebase, and the old Node middleware preset.
+
+### Check serialization
+
+SolidStart v2 defaults to JSON serialization. V1 defaulted to the smaller JavaScript format, which requires `unsafe-eval` in your Content Security Policy. Set `serialization: { mode: "js" }` on `solidStart()` only if you intentionally want the v1 behavior.
+
+### Verify the application
+
+Run the development server and production build after migrating:
+
+```package-run
+dev
+```
+
+```package-run
+build
+```
-- Entrypoint file replacements
-- Production `start` script names for generated apps
-- Auth, prerendering, metadata, and background tasks
+Test API routes, middleware order, session cookies, prerendered routes, deployment output, and any direct Nitro or H3 integrations before shipping.
diff --git a/src/routes/solid-start/v2/reference/client/mount.mdx b/src/routes/solid-start/v2/reference/client/mount.mdx
new file mode 100644
index 000000000..edc40f00d
--- /dev/null
+++ b/src/routes/solid-start/v2/reference/client/mount.mdx
@@ -0,0 +1,71 @@
+---
+title: mount
+use_cases: >-
+ client entry, hydration, app mounting
+tags:
+ - client
+ - hydration
+ - entry
+version: "2.0"
+description: >-
+ mount hydrates the client entry.
+---
+
+`mount` is Solid's [`hydrate`](/reference/rendering/hydrate) function re-exported for the SolidStart client entry.
+
+## Import
+
+```tsx
+import { mount } from "@solidjs/start/client";
+```
+
+## Type
+
+```tsx
+function mount(
+ fn: () => JSX.Element,
+ el: MountableElement
+): (() => void) | undefined;
+```
+
+## Parameters
+
+### `fn`
+
+- **Type:** `() => JSX.Element`
+- **Required:** Yes
+
+Function that returns the client app element.
+
+### `el`
+
+- **Type:** `MountableElement`
+- **Required:** Yes
+
+Element used as the hydration root.
+
+## Return value
+
+- **Type:** `(() => void) | undefined`
+
+Returns the value from [`hydrate`](/reference/rendering/hydrate).
+
+## Behavior
+
+- `mount` and `hydrate` are the same function.
+- The standard entry hydrates ` ` into the document's `#app` element.
+
+## Examples
+
+### Basic usage
+
+```tsx
+import { mount, StartClient } from "@solidjs/start/client";
+
+mount(() => , document.getElementById("app")!);
+```
+
+## Related
+
+- [`hydrate`](/reference/rendering/hydrate)
+- [`StartClient`](/solid-start/v2/reference/client/start-client)
diff --git a/src/routes/solid-start/v2/reference/client/start-client.mdx b/src/routes/solid-start/v2/reference/client/start-client.mdx
new file mode 100644
index 000000000..a0fe40ee5
--- /dev/null
+++ b/src/routes/solid-start/v2/reference/client/start-client.mdx
@@ -0,0 +1,55 @@
+---
+title: StartClient
+use_cases: >-
+ client entry, app hydration, client root
+tags:
+ - client
+ - entry
+ - component
+version: "2.0"
+description: >-
+ StartClient renders the app on the client.
+---
+
+`StartClient` is a component that renders the generated app inside the client error boundary.
+
+## Import
+
+```tsx
+import { StartClient } from "@solidjs/start/client";
+```
+
+## Type
+
+```tsx
+function StartClient(): JSX.Element;
+```
+
+## Parameters
+
+`StartClient` takes no arguments.
+
+## Return value
+
+- **Type:** `JSX.Element`
+
+Returns the client app element.
+
+## Behavior
+
+- Renders the generated `solid-start:app` module.
+- Wraps the app in the shared `ErrorBoundary`.
+
+## Examples
+
+### Basic usage
+
+```tsx
+import { mount, StartClient } from "@solidjs/start/client";
+
+mount(() => , document.getElementById("app")!);
+```
+
+## Related
+
+- [`mount`](/solid-start/v2/reference/client/mount)
diff --git a/src/routes/solid-start/v2/reference/config/solid-start.mdx b/src/routes/solid-start/v2/reference/config/solid-start.mdx
new file mode 100644
index 000000000..100d4992a
--- /dev/null
+++ b/src/routes/solid-start/v2/reference/config/solid-start.mdx
@@ -0,0 +1,167 @@
+---
+title: solidStart
+use_cases: >-
+ solidstart configuration, vite plugin, ssr mode, middleware, serialization,
+ environment variables, server functions, app root, development toolbar
+tags:
+ - config
+ - vite
+ - plugin
+ - ssr
+ - middleware
+ - environment
+version: "2.0"
+description: >-
+ Configure the SolidStart v2 Vite plugin and its application options.
+---
+
+`solidStart` returns the Vite plugins that build and run a SolidStart application with Vite's Environment API.
+
+## Import
+
+```tsx
+import { solidStart } from "@solidjs/start/config";
+```
+
+## Type
+
+```tsx
+function solidStart(options?: SolidStartOptions): PluginOption[];
+```
+
+## Basic configuration
+
+Use `solidStart()` together with a server plugin such as Nitro v3.
+
+```tsx title="vite.config.ts"
+import { nitro } from "nitro/vite";
+import { defineConfig } from "vite";
+import { solidStart } from "@solidjs/start/config";
+
+export default defineConfig({
+ plugins: [solidStart(), nitro()],
+});
+```
+
+Nitro settings do not belong inside `solidStart()`. Configure them with the top-level `nitro` property. See [`vite.config.ts`](/solid-start/v2/reference/entrypoints/vite-config).
+
+## Options
+
+### `appRoot`
+
+- **Type:** `string`
+- **Default:** `"./src"`
+
+Path to the directory that contains `app.tsx` or `app.jsx`. Relative paths such as `routeDir` are resolved from this directory.
+
+### `ssr`
+
+- **Type:** `boolean`
+- **Default:** `true`
+
+Set to `false` for client-side rendering. SolidStart swaps its server and client entrypoints to their SPA implementations while retaining file routing and server functions.
+
+### `devOverlay`
+
+- **Type:** `boolean`
+- **Default:** `true`
+
+Controls the development toolbar, which shows application errors and server function calls. Set it to `false` to hide the toolbar during development.
+
+### `experimental.islands`
+
+- **Type:** `false`
+- **Default:** `false`
+
+Reserved for islands architecture support. Islands are not currently supported, so this option only accepts `false`.
+
+### `routeDir`
+
+- **Type:** `string`
+- **Default:** `"./routes"`
+
+Route directory relative to `appRoot`.
+
+### `extensions`
+
+- **Type:** `string[]`
+- **Default:** `[]`
+
+Additional file extensions that the filesystem router and Solid compiler should process.
+
+### `middleware`
+
+- **Type:** `string`
+
+Path to the module that default-exports middleware created with [`createMiddleware`](/solid-start/v2/reference/server/create-middleware).
+
+```tsx
+solidStart({ middleware: "./src/middleware/index.ts" });
+```
+
+### `serialization`
+
+- **Type:** `{ mode?: "json" | "js"; plugins?: string }`
+- **Default:** `{ mode: "json" }`
+
+Controls server-function argument and result serialization. `json` avoids `eval` and works with a strict Content Security Policy. `js` produces a smaller payload but requires `unsafe-eval`.
+
+The `plugins` option points to a module containing custom Seroval plugins for values that Seroval does not support by default.
+
+See [Serialization](/solid-start/v2/advanced/serialization).
+
+### `solid`
+
+- **Type:** `Partial`
+
+Options forwarded to `vite-plugin-solid`.
+
+### `serverFunctions.filter`
+
+- **Type:** `{ include?: FilterPattern; exclude?: FilterPattern }`
+
+Customizes which files the `"use server"` compiler scans. By default, it includes source JavaScript and TypeScript files under `src` and excludes `node_modules`.
+
+```tsx
+solidStart({
+ serverFunctions: {
+ filter: {
+ include: ["src/**/*.{ts,tsx}", "packages/shared/**/*.ts"],
+ exclude: ["**/*.test.ts"],
+ },
+ },
+});
+```
+
+### `env`
+
+Configures SolidStart's environment-variable virtual modules.
+
+By default:
+
+- `env:server` exposes build-time variables prefixed with `SERVER_` and fails if imported by client code.
+- `env:client` exposes build-time variables prefixed with `CLIENT_` to both environments.
+- `env:server/runtime` reads runtime variables from `process.env` and is server-only.
+
+```tsx title="vite.config.ts"
+solidStart({
+ env: {
+ server: { prefix: "PRIVATE_", runtime: "node" },
+ client: { prefix: "PUBLIC_" },
+ },
+});
+```
+
+The `server.runtime` option also accepts `"cloudflare-workers"`, `"netlify-edge"`, or custom loader source code. `server.load` and `client.load` can provide custom build-time values for the current mode.
+
+## Environment boundaries
+
+SolidStart v2 recognizes `server-only` and `client-only` marker imports. Add one to a module to make an accidental import from the wrong Vite environment fail during development or build.
+
+```ts title="src/lib/db.ts"
+import "server-only";
+
+export const db = createDatabaseClient();
+```
+
+`@solidjs/start/http` and `@solidjs/start/middleware` are already marked server-only.
diff --git a/src/routes/solid-start/v2/reference/entrypoints/(0)vite-config.mdx b/src/routes/solid-start/v2/reference/entrypoints/(0)vite-config.mdx
new file mode 100644
index 000000000..d959d8df2
--- /dev/null
+++ b/src/routes/solid-start/v2/reference/entrypoints/(0)vite-config.mdx
@@ -0,0 +1,57 @@
+---
+title: vite.config.ts
+use_cases: >-
+ app config, solidstart config, vite config, nitro config, deployment config
+tags:
+ - config
+ - vite
+ - nitro
+ - entrypoint
+version: "2.0"
+description: >-
+ Configure SolidStart v2, Vite, and Nitro from vite.config.ts.
+---
+
+`vite.config.ts` is the configuration entrypoint for a SolidStart v2 application. It replaces v1's `app.config.ts`.
+
+```tsx title="vite.config.ts"
+import { nitro } from "nitro/vite";
+import { defineConfig } from "vite";
+import { solidStart } from "@solidjs/start/config";
+
+export default defineConfig({
+ plugins: [solidStart(), nitro()],
+});
+```
+
+## Responsibilities
+
+- Pass application, routing, middleware, environment, and serialization settings to [`solidStart()`](/solid-start/v2/reference/config/solid-start).
+- Add ordinary Vite plugins and options at the Vite config level.
+- Pass server, deployment, prerendering, task, and WebSocket settings through the top-level `nitro` property.
+
+```tsx title="vite.config.ts"
+import { nitro } from "nitro/vite";
+import { defineConfig } from "vite";
+import { solidStart } from "@solidjs/start/config";
+
+export default defineConfig({
+ plugins: [
+ solidStart({
+ middleware: "./src/middleware/index.ts",
+ serialization: { mode: "json" },
+ }),
+ nitro(),
+ ],
+ nitro: {
+ preset: "node_server",
+ prerender: {
+ routes: ["/"],
+ },
+ },
+});
+```
+
+SolidStart v2 requires Vite 8 or 9. The default scripts are `vite dev` and `vite build`; `vite preview` locally serves a completed production build.
+
+For the available server options and deployment presets, see the [Nitro configuration reference](https://nitro.build/config).
diff --git a/src/routes/solid-start/v2/reference/entrypoints/app.mdx b/src/routes/solid-start/v2/reference/entrypoints/app.mdx
new file mode 100644
index 000000000..587654fe0
--- /dev/null
+++ b/src/routes/solid-start/v2/reference/entrypoints/app.mdx
@@ -0,0 +1,60 @@
+---
+title: app.tsx
+use_cases: >-
+ app root, routes, root component
+tags:
+ - entrypoint
+ - app
+ - routes
+version: "2.0"
+description: >-
+ app.tsx is the app root module.
+---
+
+`app.tsx` is the resolved app root module.
+
+## Import
+
+`app.tsx` is loaded as the virtual app module.
+
+## Type
+
+```tsx
+export default function App(): JSX.Element;
+```
+
+## Parameters
+
+The default app component takes no required arguments.
+
+## Return value
+
+- **Type:** `JSX.Element`
+
+Returns the root app element.
+
+## Behavior
+
+- The Vite plugin resolves `solid-start:app` to `src/app.tsx` or `src/app.jsx`.
+- The app filename determines whether the default entry files use `.tsx` or `.jsx`.
+
+## Examples
+
+### Basic usage
+
+```tsx
+import { Router } from "@solidjs/router";
+import { FileRoutes } from "@solidjs/start/router";
+
+export default function App() {
+ return (
+
+
+
+ );
+}
+```
+
+## Related
+
+- [`FileRoutes`](/solid-start/v2/reference/routing/file-routes)
diff --git a/src/routes/solid-start/v2/reference/entrypoints/entry-client.mdx b/src/routes/solid-start/v2/reference/entrypoints/entry-client.mdx
new file mode 100644
index 000000000..d921ca1cc
--- /dev/null
+++ b/src/routes/solid-start/v2/reference/entrypoints/entry-client.mdx
@@ -0,0 +1,54 @@
+---
+title: entry-client.tsx
+use_cases: >-
+ client entry, hydration entry, browser entry
+tags:
+ - entrypoint
+ - client
+ - hydration
+version: "2.0"
+description: >-
+ entry-client.tsx mounts StartClient in the browser.
+---
+
+`entry-client.tsx` is the client entry module.
+
+## Import
+
+```tsx
+import { mount, StartClient } from "@solidjs/start/client";
+```
+
+## Type
+
+```tsx
+mount(() => , element);
+```
+
+## Parameters
+
+`entry-client.tsx` passes a `StartClient` render function and DOM element to [`mount`](/solid-start/v2/reference/client/mount).
+
+## Return value
+
+The entry module does not need to export a value.
+
+## Behavior
+
+- `solidStart()` uses `src/entry-client.tsx` as the client entry for a TypeScript app.
+- A JavaScript app whose root is `src/app.jsx` uses `src/entry-client.jsx`.
+
+## Examples
+
+### Basic usage
+
+```tsx
+import { mount, StartClient } from "@solidjs/start/client";
+
+mount(() => , document.getElementById("app")!);
+```
+
+## Related
+
+- [`mount`](/solid-start/v2/reference/client/mount)
+- [`StartClient`](/solid-start/v2/reference/client/start-client)
diff --git a/src/routes/solid-start/v2/reference/entrypoints/entry-server.mdx b/src/routes/solid-start/v2/reference/entrypoints/entry-server.mdx
new file mode 100644
index 000000000..0e3348941
--- /dev/null
+++ b/src/routes/solid-start/v2/reference/entrypoints/entry-server.mdx
@@ -0,0 +1,67 @@
+---
+title: entry-server.tsx
+use_cases: >-
+ server entry, request handler, document rendering
+tags:
+ - entrypoint
+ - server
+ - rendering
+version: "2.0"
+description: >-
+ entry-server.tsx exports the server handler.
+---
+
+`entry-server.tsx` is the server entry module.
+
+## Import
+
+```tsx
+import { createHandler, StartServer } from "@solidjs/start/server";
+```
+
+## Type
+
+```tsx
+export default createHandler((event) => );
+```
+
+## Parameters
+
+The handler callback receives a `PageEvent`.
+
+## Return value
+
+The default export is the event handler returned by [`createHandler`](/solid-start/v2/reference/server/create-handler).
+
+## Behavior
+
+- `solidStart()` uses `src/entry-server.tsx` as the server entry for a TypeScript app.
+- A JavaScript app whose root is `src/app.jsx` uses `src/entry-server.jsx`.
+- For setting different SSR modes (sync | async | stream), see [`createHandler`](/solid-start/v2/reference/server/create-handler).
+
+## Examples
+
+### Basic usage
+
+```tsx
+import { createHandler, StartServer } from "@solidjs/start/server";
+
+function Document(props) {
+ return (
+
+ {props.assets}
+
+ {props.children}
+ {props.scripts}
+
+
+ );
+}
+
+export default createHandler((event) => );
+```
+
+## Related
+
+- [`createHandler`](/solid-start/v2/reference/server/create-handler)
+- [`StartServer`](/solid-start/v2/reference/server/start-server)
diff --git a/src/routes/solid-start/v2/reference/server/create-handler.mdx b/src/routes/solid-start/v2/reference/server/create-handler.mdx
new file mode 100644
index 000000000..f42967f49
--- /dev/null
+++ b/src/routes/solid-start/v2/reference/server/create-handler.mdx
@@ -0,0 +1,103 @@
+---
+title: createHandler
+use_cases: >-
+ server entry, request handler, rendering mode
+tags:
+ - server
+ - handler
+ - rendering
+version: "2.0"
+description: >-
+ createHandler creates the server handler.
+---
+
+`createHandler` creates the handler used by the server entry.
+
+## Import
+
+```tsx
+import { createHandler } from "@solidjs/start/server";
+```
+
+## Type
+
+```tsx
+type HandlerOptions = {
+ mode?: "sync" | "async" | "stream";
+ nonce?: string;
+ renderId?: string;
+ onCompleteAll?: (options: { write: (value: any) => void }) => void;
+ onCompleteShell?: (options: { write: (value: any) => void }) => void;
+};
+
+function createHandler(
+ fn: (context: PageEvent) => JSX.Element,
+ options?:
+ | HandlerOptions
+ | ((context: PageEvent) => HandlerOptions | Promise),
+ routerLoad?: (event: FetchEvent) => Promise
+): StartHandler;
+```
+
+## Parameters
+
+### `fn`
+
+- **Type:** `(context: PageEvent) => JSX.Element`
+- **Required:** Yes
+
+Function that returns the server-rendered document.
+
+### `options`
+
+- **Type:** `HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise)`
+- **Default:** `{}`
+- **Required:** No
+
+Rendering options or a function that returns rendering options.
+
+The `options` object supports these fields:
+
+| Name | Type | Required | Default | Description |
+| ----------------- | ---------------------------------------------------- | -------- | ---------- | ----------------------------------------------- |
+| `mode` | `"sync" \| "async" \| "stream"` | No | `"stream"` | Rendering mode. |
+| `nonce` | `string` | No | None | Nonce assigned to the page event. |
+| `renderId` | `string` | No | None | Render identifier passed to the render context. |
+| `onCompleteAll` | `(options: { write: (value: any) => void }) => void` | No | None | Callback used when all stream content is ready. |
+| `onCompleteShell` | `(options: { write: (value: any) => void }) => void` | No | None | Callback used when the shell stream is ready. |
+
+### `routerLoad`
+
+- **Type:** `(event: FetchEvent) => Promise`
+- **Required:** No
+
+Optional setup function for a custom router. SolidStart calls it before creating the page event and rendering the route. Router integrations such as TanStack Router can use it to load their server-side routing state.
+
+## Return value
+
+- **Type:** `StartHandler`
+
+Returns the H3 application used by the server entry. `StartHandler` extends H3's `H3` type while keeping generated declaration files portable.
+
+## Behavior
+
+- Creates a page event for matched UI routes.
+- Matching API routes run before page rendering. For `HEAD` requests, the route `HEAD` export is used, with fallback to `GET`.
+- Synchronous mode and disabled SSR render with `renderToString` and return the HTML string.
+- Async mode returns the `renderToStream` result.
+- Stream mode is the default and returns a readable stream.
+- If page rendering sets a `Location` response header, the handler sends or writes a redirect response depending on the render phase.
+
+## Examples
+
+### Basic usage
+
+```tsx
+import { createHandler, StartServer } from "@solidjs/start/server";
+
+export default createHandler((event) => );
+```
+
+## Related
+
+- [`StartServer`](/solid-start/v2/reference/server/start-server)
diff --git a/src/routes/solid-start/v2/reference/server/start-server.mdx b/src/routes/solid-start/v2/reference/server/start-server.mdx
new file mode 100644
index 000000000..e3ef58175
--- /dev/null
+++ b/src/routes/solid-start/v2/reference/server/start-server.mdx
@@ -0,0 +1,77 @@
+---
+title: StartServer
+use_cases: >-
+ server entry, document rendering, html shell
+tags:
+ - server
+ - rendering
+ - component
+version: "2.0"
+description: >-
+ StartServer renders the app inside a document component.
+---
+
+`StartServer` is a component that renders the generated app inside the provided document component.
+
+## Import
+
+```tsx
+import { StartServer } from "@solidjs/start/server";
+```
+
+## Type
+
+```tsx
+type DocumentComponentProps = {
+ assets?: JSX.Element;
+ scripts: JSX.Element;
+ children?: JSX.Element;
+};
+
+function StartServer(props: {
+ document: Component;
+}): JSX.Element;
+```
+
+## Props
+
+### `document`
+
+- **Type:** `Component`
+- **Optional:** No
+
+Document component rendered around the app.
+
+## Behavior
+
+- Reads the current request event as a `PageEvent`.
+- Registers page assets with `useAssets`.
+- Renders `` before the document component.
+- Passes `assets`, `scripts`, and `children` to the document component.
+- Wraps the app with error boundaries.
+
+## Examples
+
+### Basic usage
+
+```tsx
+import { createHandler, StartServer } from "@solidjs/start/server";
+
+function Document(props) {
+ return (
+
+ {props.assets}
+
+ {props.children}
+ {props.scripts}
+
+
+ );
+}
+
+export default createHandler((event) => );
+```
+
+## Related
+
+- [`createHandler`](/solid-start/v2/reference/server/create-handler)
diff --git a/src/routes/solid-start/v2/reference/server/use-server.mdx b/src/routes/solid-start/v2/reference/server/use-server.mdx
index f7f3703ba..947a74e79 100644
--- a/src/routes/solid-start/v2/reference/server/use-server.mdx
+++ b/src/routes/solid-start/v2/reference/server/use-server.mdx
@@ -60,7 +60,7 @@ export async function logMessage(message: string) {
```
:::note[Using with query]
-When wrapping a server function with [`query`](/solid-router/reference/data-apis/query), place `"use server"` inside the inner function rather than at the file level. A file-level directive turns the whole module — including the `query` wrapper that also runs on the client — into a server reference.
+When wrapping a server function with [`query`](/solid-router/reference/data-apis/query), place `"use server"` inside the inner function rather than at the file level. A file-level directive turns the whole module, including the `query` wrapper that also runs on the client, into a server reference.
```tsx
export const logMessage = query(async (message: string) => {