diff --git a/e2e/solid-router/generator-cli-only/.gitignore b/e2e/solid-router/generator-cli-only/.gitignore
new file mode 100644
index 00000000000..218ef7614ba
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/.gitignore
@@ -0,0 +1,11 @@
+node_modules
+.DS_Store
+dist
+dist-hash
+dist-ssr
+*.local
+
+/test-results/
+/playwright-report/
+/blob-report/
+/playwright/.cache/
\ No newline at end of file
diff --git a/e2e/solid-router/generator-cli-only/index.html b/e2e/solid-router/generator-cli-only/index.html
new file mode 100644
index 00000000000..9b6335c0ac1
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/e2e/solid-router/generator-cli-only/package.json b/e2e/solid-router/generator-cli-only/package.json
new file mode 100644
index 00000000000..8e0082d3d74
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "tanstack-solid-router-e2e-react-generator-cli-only",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "tsr generate && vite --port 3000",
+ "dev:e2e": "tsr generate && vite",
+ "build": "tsr generate && vite build && tsc --noEmit",
+ "serve": "vite preview",
+ "start": "tsr generate && vite",
+ "test:e2e": "rm -rf port*.txt; playwright test --project=chromium"
+ },
+ "dependencies": {
+ "@tailwindcss/postcss": "^4.1.15",
+ "@tanstack/solid-router": "workspace:^",
+ "@tanstack/solid-router-devtools": "workspace:^",
+ "@tanstack/router-cli": "workspace:^",
+ "postcss": "^8.5.1",
+ "solid-js": "^1.9.9",
+ "redaxios": "^0.5.1",
+ "tailwindcss": "^4.1.15"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.50.1",
+ "@tanstack/router-e2e-utils": "workspace:^",
+ "vite-plugin-solid": "^2.11.10",
+ "vite": "^7.1.7"
+ }
+}
diff --git a/e2e/solid-router/generator-cli-only/playwright.config.ts b/e2e/solid-router/generator-cli-only/playwright.config.ts
new file mode 100644
index 00000000000..608b920d90d
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/playwright.config.ts
@@ -0,0 +1,41 @@
+import { defineConfig, devices } from '@playwright/test'
+import {
+ getDummyServerPort,
+ getTestServerPort,
+} from '@tanstack/router-e2e-utils'
+import packageJson from './package.json' with { type: 'json' }
+
+const PORT = await getTestServerPort(packageJson.name)
+const EXTERNAL_PORT = await getDummyServerPort(packageJson.name)
+const baseURL = `http://localhost:${PORT}`
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './tests',
+ workers: 1,
+
+ reporter: [['line']],
+
+ globalSetup: './tests/setup/global.setup.ts',
+ globalTeardown: './tests/setup/global.teardown.ts',
+
+ use: {
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL,
+ },
+
+ webServer: {
+ command: `VITE_NODE_ENV="test" VITE_EXTERNAL_PORT=${EXTERNAL_PORT} VITE_SERVER_PORT=${PORT} pnpm build && VITE_SERVER_PORT=${PORT} pnpm serve --port ${PORT}`,
+ url: baseURL,
+ reuseExistingServer: !process.env.CI,
+ stdout: 'pipe',
+ },
+
+ projects: [
+ {
+ name: 'chromium',
+ use: { ...devices['Desktop Chrome'] },
+ },
+ ],
+})
diff --git a/e2e/solid-router/generator-cli-only/postcss.config.mjs b/e2e/solid-router/generator-cli-only/postcss.config.mjs
new file mode 100644
index 00000000000..a7f73a2d1d7
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/postcss.config.mjs
@@ -0,0 +1,5 @@
+export default {
+ plugins: {
+ '@tailwindcss/postcss': {},
+ },
+}
diff --git a/e2e/solid-router/generator-cli-only/src/main.tsx b/e2e/solid-router/generator-cli-only/src/main.tsx
new file mode 100644
index 00000000000..fc12c765703
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/main.tsx
@@ -0,0 +1,25 @@
+import { RouterProvider, createRouter } from '@tanstack/solid-router'
+import { render } from 'solid-js/web'
+import { routeTree } from './routeTree.gen'
+import './styles.css'
+
+// Set up a Router instance
+const router = createRouter({
+ routeTree,
+ defaultPreload: 'intent',
+ defaultStaleTime: 5000,
+ scrollRestoration: true,
+})
+
+// Register things for typesafety
+declare module '@tanstack/solid-router' {
+ interface Register {
+ router: typeof router
+ }
+}
+
+const rootElement = document.getElementById('app')!
+
+if (!rootElement.innerHTML) {
+ render(() => , rootElement)
+}
diff --git a/e2e/solid-router/generator-cli-only/src/posts.ts b/e2e/solid-router/generator-cli-only/src/posts.ts
new file mode 100644
index 00000000000..e859645746b
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/posts.ts
@@ -0,0 +1,36 @@
+import axios from 'redaxios'
+
+export class NotFoundError extends Error {}
+
+type PostType = {
+ id: string
+ title: string
+ body: string
+}
+
+let queryURL = 'https://jsonplaceholder.typicode.com'
+
+if (import.meta.env.VITE_NODE_ENV === 'test') {
+ queryURL = `http://localhost:${import.meta.env.VITE_EXTERNAL_PORT}`
+}
+
+export const fetchPosts = async () => {
+ console.info('Fetching posts...')
+ return axios
+ .get>(`${queryURL}/posts`)
+ .then((r) => r.data.slice(0, 10))
+}
+
+export const fetchPost = async (postId: string) => {
+ console.info(`Fetching post with id ${postId}...`)
+ const post = await axios
+ .get(`${queryURL}/posts/${postId}`)
+ .then((r) => r.data)
+
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (!post) {
+ throw new NotFoundError(`Post with id "${postId}" not found!`)
+ }
+
+ return post
+}
diff --git a/e2e/solid-router/generator-cli-only/src/routeTree.gen.ts b/e2e/solid-router/generator-cli-only/src/routeTree.gen.ts
new file mode 100644
index 00000000000..ae0f54ca678
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/routeTree.gen.ts
@@ -0,0 +1,230 @@
+/* eslint-disable */
+
+// @ts-nocheck
+
+// noinspection JSUnusedGlobalSymbols
+
+// This file was automatically generated by TanStack Router.
+// You should NOT make any changes in this file as it will be overwritten.
+// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
+
+import { Route as rootRouteImport } from './routes/__root'
+import { Route as PathlessLayoutRouteImport } from './routes/_pathlessLayout'
+import { Route as PostsRouteRouteImport } from './routes/posts.route'
+import { Route as IndexRouteImport } from './routes/index'
+import { Route as PostsIndexRouteImport } from './routes/posts.index'
+import { Route as PostsPostIdRouteImport } from './routes/posts.$postId'
+import { Route as PathlessLayoutNestedLayoutRouteImport } from './routes/_pathlessLayout/_nested-layout'
+import { Route as PathlessLayoutNestedLayoutRouteBRouteImport } from './routes/_pathlessLayout/_nested-layout/route-b'
+import { Route as PathlessLayoutNestedLayoutRouteARouteImport } from './routes/_pathlessLayout/_nested-layout/route-a'
+
+const PathlessLayoutRoute = PathlessLayoutRouteImport.update({
+ id: '/_pathlessLayout',
+ getParentRoute: () => rootRouteImport,
+} as any)
+const PostsRouteRoute = PostsRouteRouteImport.update({
+ id: '/posts',
+ path: '/posts',
+ getParentRoute: () => rootRouteImport,
+} as any)
+const IndexRoute = IndexRouteImport.update({
+ id: '/',
+ path: '/',
+ getParentRoute: () => rootRouteImport,
+} as any)
+const PostsIndexRoute = PostsIndexRouteImport.update({
+ id: '/',
+ path: '/',
+ getParentRoute: () => PostsRouteRoute,
+} as any)
+const PostsPostIdRoute = PostsPostIdRouteImport.update({
+ id: '/$postId',
+ path: '/$postId',
+ getParentRoute: () => PostsRouteRoute,
+} as any)
+const PathlessLayoutNestedLayoutRoute =
+ PathlessLayoutNestedLayoutRouteImport.update({
+ id: '/_nested-layout',
+ getParentRoute: () => PathlessLayoutRoute,
+ } as any)
+const PathlessLayoutNestedLayoutRouteBRoute =
+ PathlessLayoutNestedLayoutRouteBRouteImport.update({
+ id: '/route-b',
+ path: '/route-b',
+ getParentRoute: () => PathlessLayoutNestedLayoutRoute,
+ } as any)
+const PathlessLayoutNestedLayoutRouteARoute =
+ PathlessLayoutNestedLayoutRouteARouteImport.update({
+ id: '/route-a',
+ path: '/route-a',
+ getParentRoute: () => PathlessLayoutNestedLayoutRoute,
+ } as any)
+
+export interface FileRoutesByFullPath {
+ '/': typeof IndexRoute
+ '/posts': typeof PostsRouteRouteWithChildren
+ '/posts/$postId': typeof PostsPostIdRoute
+ '/posts/': typeof PostsIndexRoute
+ '/route-a': typeof PathlessLayoutNestedLayoutRouteARoute
+ '/route-b': typeof PathlessLayoutNestedLayoutRouteBRoute
+}
+export interface FileRoutesByTo {
+ '/': typeof IndexRoute
+ '/posts/$postId': typeof PostsPostIdRoute
+ '/posts': typeof PostsIndexRoute
+ '/route-a': typeof PathlessLayoutNestedLayoutRouteARoute
+ '/route-b': typeof PathlessLayoutNestedLayoutRouteBRoute
+}
+export interface FileRoutesById {
+ __root__: typeof rootRouteImport
+ '/': typeof IndexRoute
+ '/posts': typeof PostsRouteRouteWithChildren
+ '/_pathlessLayout': typeof PathlessLayoutRouteWithChildren
+ '/_pathlessLayout/_nested-layout': typeof PathlessLayoutNestedLayoutRouteWithChildren
+ '/posts/$postId': typeof PostsPostIdRoute
+ '/posts/': typeof PostsIndexRoute
+ '/_pathlessLayout/_nested-layout/route-a': typeof PathlessLayoutNestedLayoutRouteARoute
+ '/_pathlessLayout/_nested-layout/route-b': typeof PathlessLayoutNestedLayoutRouteBRoute
+}
+export interface FileRouteTypes {
+ fileRoutesByFullPath: FileRoutesByFullPath
+ fullPaths:
+ | '/'
+ | '/posts'
+ | '/posts/$postId'
+ | '/posts/'
+ | '/route-a'
+ | '/route-b'
+ fileRoutesByTo: FileRoutesByTo
+ to: '/' | '/posts/$postId' | '/posts' | '/route-a' | '/route-b'
+ id:
+ | '__root__'
+ | '/'
+ | '/posts'
+ | '/_pathlessLayout'
+ | '/_pathlessLayout/_nested-layout'
+ | '/posts/$postId'
+ | '/posts/'
+ | '/_pathlessLayout/_nested-layout/route-a'
+ | '/_pathlessLayout/_nested-layout/route-b'
+ fileRoutesById: FileRoutesById
+}
+export interface RootRouteChildren {
+ IndexRoute: typeof IndexRoute
+ PostsRouteRoute: typeof PostsRouteRouteWithChildren
+ PathlessLayoutRoute: typeof PathlessLayoutRouteWithChildren
+}
+
+declare module '@tanstack/solid-router' {
+ interface FileRoutesByPath {
+ '/_pathlessLayout': {
+ id: '/_pathlessLayout'
+ path: ''
+ fullPath: ''
+ preLoaderRoute: typeof PathlessLayoutRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ '/posts': {
+ id: '/posts'
+ path: '/posts'
+ fullPath: '/posts'
+ preLoaderRoute: typeof PostsRouteRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ '/': {
+ id: '/'
+ path: '/'
+ fullPath: '/'
+ preLoaderRoute: typeof IndexRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ '/posts/': {
+ id: '/posts/'
+ path: '/'
+ fullPath: '/posts/'
+ preLoaderRoute: typeof PostsIndexRouteImport
+ parentRoute: typeof PostsRouteRoute
+ }
+ '/posts/$postId': {
+ id: '/posts/$postId'
+ path: '/$postId'
+ fullPath: '/posts/$postId'
+ preLoaderRoute: typeof PostsPostIdRouteImport
+ parentRoute: typeof PostsRouteRoute
+ }
+ '/_pathlessLayout/_nested-layout': {
+ id: '/_pathlessLayout/_nested-layout'
+ path: ''
+ fullPath: ''
+ preLoaderRoute: typeof PathlessLayoutNestedLayoutRouteImport
+ parentRoute: typeof PathlessLayoutRoute
+ }
+ '/_pathlessLayout/_nested-layout/route-b': {
+ id: '/_pathlessLayout/_nested-layout/route-b'
+ path: '/route-b'
+ fullPath: '/route-b'
+ preLoaderRoute: typeof PathlessLayoutNestedLayoutRouteBRouteImport
+ parentRoute: typeof PathlessLayoutNestedLayoutRoute
+ }
+ '/_pathlessLayout/_nested-layout/route-a': {
+ id: '/_pathlessLayout/_nested-layout/route-a'
+ path: '/route-a'
+ fullPath: '/route-a'
+ preLoaderRoute: typeof PathlessLayoutNestedLayoutRouteARouteImport
+ parentRoute: typeof PathlessLayoutNestedLayoutRoute
+ }
+ }
+}
+
+interface PostsRouteRouteChildren {
+ PostsPostIdRoute: typeof PostsPostIdRoute
+ PostsIndexRoute: typeof PostsIndexRoute
+}
+
+const PostsRouteRouteChildren: PostsRouteRouteChildren = {
+ PostsPostIdRoute: PostsPostIdRoute,
+ PostsIndexRoute: PostsIndexRoute,
+}
+
+const PostsRouteRouteWithChildren = PostsRouteRoute._addFileChildren(
+ PostsRouteRouteChildren,
+)
+
+interface PathlessLayoutNestedLayoutRouteChildren {
+ PathlessLayoutNestedLayoutRouteARoute: typeof PathlessLayoutNestedLayoutRouteARoute
+ PathlessLayoutNestedLayoutRouteBRoute: typeof PathlessLayoutNestedLayoutRouteBRoute
+}
+
+const PathlessLayoutNestedLayoutRouteChildren: PathlessLayoutNestedLayoutRouteChildren =
+ {
+ PathlessLayoutNestedLayoutRouteARoute:
+ PathlessLayoutNestedLayoutRouteARoute,
+ PathlessLayoutNestedLayoutRouteBRoute:
+ PathlessLayoutNestedLayoutRouteBRoute,
+ }
+
+const PathlessLayoutNestedLayoutRouteWithChildren =
+ PathlessLayoutNestedLayoutRoute._addFileChildren(
+ PathlessLayoutNestedLayoutRouteChildren,
+ )
+
+interface PathlessLayoutRouteChildren {
+ PathlessLayoutNestedLayoutRoute: typeof PathlessLayoutNestedLayoutRouteWithChildren
+}
+
+const PathlessLayoutRouteChildren: PathlessLayoutRouteChildren = {
+ PathlessLayoutNestedLayoutRoute: PathlessLayoutNestedLayoutRouteWithChildren,
+}
+
+const PathlessLayoutRouteWithChildren = PathlessLayoutRoute._addFileChildren(
+ PathlessLayoutRouteChildren,
+)
+
+const rootRouteChildren: RootRouteChildren = {
+ IndexRoute: IndexRoute,
+ PostsRouteRoute: PostsRouteRouteWithChildren,
+ PathlessLayoutRoute: PathlessLayoutRouteWithChildren,
+}
+export const routeTree = rootRouteImport
+ ._addFileChildren(rootRouteChildren)
+ ._addFileTypes()
diff --git a/e2e/solid-router/generator-cli-only/src/routes/__root.tsx b/e2e/solid-router/generator-cli-only/src/routes/__root.tsx
new file mode 100644
index 00000000000..67bc9248fab
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/routes/__root.tsx
@@ -0,0 +1,61 @@
+import { Link, Outlet, createRootRoute } from '@tanstack/solid-router'
+import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
+
+export const Route = createRootRoute({
+ component: RootComponent,
+ notFoundComponent: () => {
+ return (
+
+
This is the notFoundComponent configured on root route
+
Start Over
+
+ )
+ },
+})
+
+function RootComponent() {
+ return (
+ <>
+
+
+ Home
+ {' '}
+
+ Posts
+ {' '}
+
+ Pathless Layout
+ {' '}
+
+ This Route Does Not Exist
+
+
+
+
+ {/* Start rendering router matches */}
+
+ >
+ )
+}
diff --git a/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout.tsx b/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout.tsx
new file mode 100644
index 00000000000..b52af5379be
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout.tsx
@@ -0,0 +1,16 @@
+import { Outlet, createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/_pathlessLayout')({
+ component: LayoutComponent,
+})
+
+function LayoutComponent() {
+ return (
+
+
I'm a pathless layout
+
+
+
+
+ )
+}
diff --git a/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout/_nested-layout.tsx b/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout/_nested-layout.tsx
new file mode 100644
index 00000000000..f54a42abb4a
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout/_nested-layout.tsx
@@ -0,0 +1,34 @@
+import { Link, Outlet, createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/_pathlessLayout/_nested-layout')({
+ component: LayoutComponent,
+})
+
+function LayoutComponent() {
+ return (
+
+
I'm a nested pathless layout
+
+
+ Go to route A
+
+
+ Go to route B
+
+
+
+
+
+
+ )
+}
diff --git a/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout/_nested-layout/route-a.tsx b/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout/_nested-layout/route-a.tsx
new file mode 100644
index 00000000000..6f87493831b
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout/_nested-layout/route-a.tsx
@@ -0,0 +1,11 @@
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/_pathlessLayout/_nested-layout/route-a')(
+ {
+ component: LayoutAComponent,
+ },
+)
+
+function LayoutAComponent() {
+ return I'm layout A!
+}
diff --git a/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout/_nested-layout/route-b.tsx b/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout/_nested-layout/route-b.tsx
new file mode 100644
index 00000000000..fac72b0da65
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/routes/_pathlessLayout/_nested-layout/route-b.tsx
@@ -0,0 +1,11 @@
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/_pathlessLayout/_nested-layout/route-b')(
+ {
+ component: LayoutBComponent,
+ },
+)
+
+function LayoutBComponent() {
+ return I'm layout B!
+}
diff --git a/e2e/solid-router/generator-cli-only/src/routes/index.tsx b/e2e/solid-router/generator-cli-only/src/routes/index.tsx
new file mode 100644
index 00000000000..bdfb4c76768
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/routes/index.tsx
@@ -0,0 +1,13 @@
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/')({
+ component: Home,
+})
+
+function Home() {
+ return (
+
+
Welcome Home!
+
+ )
+}
diff --git a/e2e/solid-router/generator-cli-only/src/routes/posts.$postId.tsx b/e2e/solid-router/generator-cli-only/src/routes/posts.$postId.tsx
new file mode 100644
index 00000000000..86ac48fcd9c
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/routes/posts.$postId.tsx
@@ -0,0 +1,27 @@
+import { ErrorComponent, createFileRoute } from '@tanstack/solid-router'
+import { fetchPost } from '../posts'
+import type { ErrorComponentProps } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/posts/$postId')({
+ loader: async ({ params: { postId } }) => fetchPost(postId),
+ errorComponent: PostErrorComponent,
+ notFoundComponent: () => {
+ return Post not found
+ },
+ component: PostComponent,
+})
+
+export function PostErrorComponent({ error }: ErrorComponentProps) {
+ return
+}
+
+function PostComponent() {
+ const post = Route.useLoaderData()
+
+ return (
+
+
{post().title}
+
{post().body}
+
+ )
+}
diff --git a/e2e/solid-router/generator-cli-only/src/routes/posts.index.tsx b/e2e/solid-router/generator-cli-only/src/routes/posts.index.tsx
new file mode 100644
index 00000000000..33d0386c195
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/routes/posts.index.tsx
@@ -0,0 +1,9 @@
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/posts/')({
+ component: PostsIndexComponent,
+})
+
+function PostsIndexComponent() {
+ return Select a post.
+}
diff --git a/e2e/solid-router/generator-cli-only/src/routes/posts.route.tsx b/e2e/solid-router/generator-cli-only/src/routes/posts.route.tsx
new file mode 100644
index 00000000000..4c9cb453739
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/routes/posts.route.tsx
@@ -0,0 +1,38 @@
+import { Link, Outlet, createFileRoute } from '@tanstack/solid-router'
+import { fetchPosts } from '../posts'
+
+export const Route = createFileRoute('/posts')({
+ loader: fetchPosts,
+ component: PostsLayoutComponent,
+})
+
+function PostsLayoutComponent() {
+ const posts = Route.useLoaderData()
+
+ return (
+
+ )
+}
diff --git a/e2e/solid-router/generator-cli-only/src/styles.css b/e2e/solid-router/generator-cli-only/src/styles.css
new file mode 100644
index 00000000000..37a1064738a
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/src/styles.css
@@ -0,0 +1,21 @@
+@import 'tailwindcss';
+
+@layer base {
+ *,
+ ::after,
+ ::before,
+ ::backdrop,
+ ::file-selector-button {
+ border-color: var(--color-gray-200, currentcolor);
+ }
+}
+
+html {
+ color-scheme: light dark;
+}
+* {
+ @apply border-gray-200 dark:border-gray-800;
+}
+body {
+ @apply bg-gray-50 text-gray-950 dark:bg-gray-900 dark:text-gray-200;
+}
diff --git a/e2e/solid-router/generator-cli-only/tests/app.spec.ts b/e2e/solid-router/generator-cli-only/tests/app.spec.ts
new file mode 100644
index 00000000000..5a83a314f20
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/tests/app.spec.ts
@@ -0,0 +1,35 @@
+import { expect, test } from '@playwright/test'
+
+test.beforeEach(async ({ page }) => {
+ await page.goto('/')
+})
+
+test('Navigating to a post page', async ({ page }) => {
+ await page.getByRole('link', { name: 'Posts', exact: true }).click()
+ await page.getByRole('link', { name: 'sunt aut facere repe' }).click()
+ await expect(page.getByRole('heading')).toContainText('sunt aut facere')
+})
+
+test('Navigating nested pathless layouts', async ({ page }) => {
+ await page.getByRole('link', { name: 'Pathless Layout', exact: true }).click()
+
+ await expect(page.locator('#app')).toContainText("I'm a pathless layout")
+ await expect(page.locator('#app')).toContainText(
+ "I'm a nested pathless layout",
+ )
+
+ await page.getByRole('link', { name: 'Go to route A' }).click()
+ await expect(page.locator('#app')).toContainText("I'm layout A!")
+
+ await page.getByRole('link', { name: 'Go to route B' }).click()
+ await expect(page.locator('#app')).toContainText("I'm layout B!")
+})
+
+test('Navigating to a not-found route', async ({ page }) => {
+ await page.getByRole('link', { name: 'This Route Does Not Exist' }).click()
+ await expect(page.getByRole('paragraph')).toContainText(
+ 'This is the notFoundComponent configured on root route',
+ )
+ await page.getByRole('link', { name: 'Start Over' }).click()
+ await expect(page.getByRole('heading')).toContainText('Welcome Home!')
+})
diff --git a/e2e/solid-router/generator-cli-only/tests/setup/global.setup.ts b/e2e/solid-router/generator-cli-only/tests/setup/global.setup.ts
new file mode 100644
index 00000000000..3593d10ab90
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/tests/setup/global.setup.ts
@@ -0,0 +1,6 @@
+import { e2eStartDummyServer } from '@tanstack/router-e2e-utils'
+import packageJson from '../../package.json' with { type: 'json' }
+
+export default async function setup() {
+ await e2eStartDummyServer(packageJson.name)
+}
diff --git a/e2e/solid-router/generator-cli-only/tests/setup/global.teardown.ts b/e2e/solid-router/generator-cli-only/tests/setup/global.teardown.ts
new file mode 100644
index 00000000000..62fd79911cc
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/tests/setup/global.teardown.ts
@@ -0,0 +1,6 @@
+import { e2eStopDummyServer } from '@tanstack/router-e2e-utils'
+import packageJson from '../../package.json' with { type: 'json' }
+
+export default async function teardown() {
+ await e2eStopDummyServer(packageJson.name)
+}
diff --git a/e2e/solid-router/generator-cli-only/tsconfig.json b/e2e/solid-router/generator-cli-only/tsconfig.json
new file mode 100644
index 00000000000..44cb3c81d16
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "strict": true,
+ "esModuleInterop": true,
+ "jsx": "preserve",
+ "jsxImportSource": "solid-js",
+ "target": "ESNext",
+ "moduleResolution": "Bundler",
+ "module": "ESNext",
+ "resolveJsonModule": true,
+ "allowJs": true,
+ "skipLibCheck": true,
+ "types": ["vite/client"]
+ },
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/e2e/solid-router/generator-cli-only/tsr.config.json b/e2e/solid-router/generator-cli-only/tsr.config.json
new file mode 100644
index 00000000000..570e09bf5ac
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/tsr.config.json
@@ -0,0 +1,5 @@
+{
+ "routesDirectory": "./src/routes",
+ "generatedRouteTree": "./src/routeTree.gen.ts",
+ "target": "solid"
+}
diff --git a/e2e/solid-router/generator-cli-only/vite.config.js b/e2e/solid-router/generator-cli-only/vite.config.js
new file mode 100644
index 00000000000..05041cc6d83
--- /dev/null
+++ b/e2e/solid-router/generator-cli-only/vite.config.js
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vite'
+import solid from 'vite-plugin-solid'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [solid()],
+})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index dae55a36887..f4830afb555 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2405,6 +2405,46 @@ importers:
specifier: ^2.11.10
version: 2.11.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.9)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+ e2e/solid-router/generator-cli-only:
+ dependencies:
+ '@tailwindcss/postcss':
+ specifier: ^4.1.15
+ version: 4.1.15
+ '@tanstack/router-cli':
+ specifier: workspace:*
+ version: link:../../../packages/router-cli
+ '@tanstack/solid-router':
+ specifier: workspace:^
+ version: link:../../../packages/solid-router
+ '@tanstack/solid-router-devtools':
+ specifier: workspace:^
+ version: link:../../../packages/solid-router-devtools
+ postcss:
+ specifier: ^8.5.1
+ version: 8.5.6
+ redaxios:
+ specifier: ^0.5.1
+ version: 0.5.1
+ solid-js:
+ specifier: 1.9.9
+ version: 1.9.9
+ tailwindcss:
+ specifier: ^4.1.15
+ version: 4.1.15
+ devDependencies:
+ '@playwright/test':
+ specifier: ^1.52.0
+ version: 1.52.0
+ '@tanstack/router-e2e-utils':
+ specifier: workspace:^
+ version: link:../../e2e-utils
+ vite:
+ specifier: ^7.1.7
+ version: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+ vite-plugin-solid:
+ specifier: ^2.11.10
+ version: 2.11.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.9)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+
e2e/solid-router/rspack-basic-file-based:
dependencies:
'@tanstack/solid-router':