diff --git a/tests/test/app/server-only/api+api.tsx b/tests/test/app/server-only/api+api.tsx
new file mode 100644
index 000000000..295bf348c
--- /dev/null
+++ b/tests/test/app/server-only/api+api.tsx
@@ -0,0 +1,8 @@
+// import 'server-only'
+
+export async function GET() {
+ return new Response(JSON.stringify({ success: true }), {
+ status: 200,
+ headers: { 'Content-Type': 'application/json' },
+ })
+}
diff --git a/tests/test/app/server-only/spa+spa.tsx b/tests/test/app/server-only/spa+spa.tsx
new file mode 100644
index 000000000..4bf115318
--- /dev/null
+++ b/tests/test/app/server-only/spa+spa.tsx
@@ -0,0 +1,8 @@
+// import 'server-only'
+// import { Text } from 'tamagui'
+
+// export default () => This should't render since 'server-only' is imported. If you see this in the browser, things are going wrong.
+
+// Can't test like this since it'll break the build
+
+export default () => null
diff --git a/tests/test/package.json b/tests/test/package.json
index 7301ac837..a68ad5379 100644
--- a/tests/test/package.json
+++ b/tests/test/package.json
@@ -30,6 +30,7 @@
"react-native-screens": "4.4.0",
"react-native-svg": "15.8.0",
"react-native-web": "^0.19.12",
+ "server-only": "^0.0.1",
"tamagui": "^1.121.6"
},
"devDependencies": {
diff --git a/tests/test/routes.d.ts b/tests/test/routes.d.ts
index 70746c8ce..3333b39d2 100644
--- a/tests/test/routes.d.ts
+++ b/tests/test/routes.d.ts
@@ -3,7 +3,7 @@ import type { OneRouter } from 'one'
declare module 'one' {
export namespace OneRouter {
export interface __routes extends Record {
- StaticRoutes: `/` | `/(blog)` | `/(blog)/blog/my-first-post` | `/(marketing)/about` | `/_sitemap` | `/about` | `/blog/my-first-post` | `/middleware` | `/not-found/deep/test` | `/not-found/fallback/test` | `/not-found/test` | `/spa/spapage` | `/ssr/basic` | `/sub-page` | `/sub-page/sub` | `/sub-page/sub2`
+ StaticRoutes: `/` | `/(blog)` | `/(blog)/blog/my-first-post` | `/(marketing)/about` | `/_sitemap` | `/about` | `/blog/my-first-post` | `/middleware` | `/not-found/deep/test` | `/not-found/fallback/test` | `/not-found/test` | `/server-only/spa` | `/spa/spapage` | `/ssr/basic` | `/sub-page` | `/sub-page/sub` | `/sub-page/sub2`
DynamicRoutes: `/not-found/+not-found` | `/not-found/deep/+not-found` | `/spa/${OneRouter.SingleRoutePart}` | `/ssr/${OneRouter.SingleRoutePart}` | `/ssr/${string}`
DynamicRouteTemplate: `/not-found/+not-found` | `/not-found/deep/+not-found` | `/spa/[spaparams]` | `/ssr/[...rest]` | `/ssr/[param]`
IsTyped: true
diff --git a/tests/test/tests/server-only.test.ts b/tests/test/tests/server-only.test.ts
new file mode 100644
index 000000000..d8f030651
--- /dev/null
+++ b/tests/test/tests/server-only.test.ts
@@ -0,0 +1,13 @@
+import { describe, expect, test, it } from 'vitest'
+import { fetchDevAndProd } from './utils/fetchDevAndProd'
+
+describe('server-only', () => {
+ it('should not break API routes', async () => {
+ const [devRes, prodRes] = await fetchDevAndProd('/server-only/api', 'text')
+ debugger
+ })
+ it('should break SPA routes', async () => {
+ const [devRes, prodRes] = await fetchDevAndProd('/server-only/spa', 'text')
+ debugger
+ })
+})
diff --git a/tests/test/tests/test-middleware.test.ts b/tests/test/tests/test-middleware.test.ts
index bf5374a33..caf0cd9fc 100644
--- a/tests/test/tests/test-middleware.test.ts
+++ b/tests/test/tests/test-middleware.test.ts
@@ -1,22 +1,5 @@
import { describe, expect, test } from 'vitest'
-
-// set this up for testing, pausing
-async function fetchDevAndProd(path = '/', type: 'text' | 'json' | 'headers') {
- return await Promise.all([
- fetch(`http://localhost:3111${path}`).then((res) => {
- if (type === 'headers') {
- return res.headers
- }
- return res[type]()
- }),
- fetch(`http://localhost:3112${path}`).then((res) => {
- if (type === 'headers') {
- return res.headers
- }
- return res[type]()
- }),
- ] as const)
-}
+import { fetchDevAndProd } from './utils/fetchDevAndProd'
describe('Middleware', () => {
test('root middleware doesnt intercept', async () => {
diff --git a/tests/test/tests/utils/fetchDevAndProd.ts b/tests/test/tests/utils/fetchDevAndProd.ts
new file mode 100644
index 000000000..62d28c034
--- /dev/null
+++ b/tests/test/tests/utils/fetchDevAndProd.ts
@@ -0,0 +1,17 @@
+// set this up for testing, pausing
+export async function fetchDevAndProd(path = '/', type: 'text' | 'json' | 'headers') {
+ return await Promise.all([
+ fetch(`http://localhost:3111${path}`).then((res) => {
+ if (type === 'headers') {
+ return res.headers
+ }
+ return res[type]()
+ }),
+ fetch(`http://localhost:3112${path}`).then((res) => {
+ if (type === 'headers') {
+ return res.headers
+ }
+ return res[type]()
+ }),
+ ] as const)
+}
diff --git a/yarn.lock b/yarn.lock
index cb96513f2..235e936e3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -24866,6 +24866,13 @@ __metadata:
languageName: node
linkType: hard
+"server-only@npm:^0.0.1":
+ version: 0.0.1
+ resolution: "server-only@npm:0.0.1"
+ checksum: 10/c432348956641ea3f460af8dc3765f3a1bdbcf7a1e0205b0756d868e6e6fe8934cdee6bff68401a1dd49ba4a831c75916517a877446d54b334f7de36fa273e53
+ languageName: node
+ linkType: hard
+
"set-blocking@npm:^2.0.0":
version: 2.0.0
resolution: "set-blocking@npm:2.0.0"
@@ -26255,6 +26262,7 @@ __metadata:
react-native-screens: "npm:4.4.0"
react-native-svg: "npm:15.8.0"
react-native-web: "npm:^0.19.12"
+ server-only: "npm:^0.0.1"
tamagui: "npm:^1.121.6"
tsx: "npm:^4.19.0"
vite: "npm:^6.0.6"