From 09aa000b02e9f375379b946f51aac2cdf2dfd939 Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Wed, 12 Nov 2025 20:37:16 +0100 Subject: [PATCH 1/2] docs(solid-start): start-large example --- examples/solid/start-large/.gitignore | 19 ++ .../solid/start-large/.vscode/settings.json | 11 + examples/solid/start-large/package.json | 36 +++ examples/solid/start-large/postcss.config.mjs | 5 + .../solid/start-large/src/createRoutes.mjs | 49 ++++ .../solid/start-large/src/routeTree.gen.ts | 239 ++++++++++++++++++ examples/solid/start-large/src/router.tsx | 15 ++ .../solid/start-large/src/routes/__root.tsx | 56 ++++ .../solid/start-large/src/routes/absolute.tsx | 18 ++ .../solid/start-large/src/routes/index.tsx | 13 + .../start-large/src/routes/linkProps.tsx | 72 ++++++ .../src/routes/params/$paramsPlaceholder.tsx | 76 ++++++ .../start-large/src/routes/params/route.tsx | 5 + .../solid/start-large/src/routes/relative.tsx | 19 ++ .../start-large/src/routes/search/route.tsx | 11 + .../src/routes/search/searchPlaceholder.tsx | 89 +++++++ examples/solid/start-large/src/styles.css | 30 +++ .../solid/start-large/src/typePrimitives.tsx | 50 ++++ examples/solid/start-large/tsconfig.json | 23 ++ examples/solid/start-large/vite.config.ts | 17 ++ pnpm-lock.yaml | 52 ++++ 21 files changed, 905 insertions(+) create mode 100644 examples/solid/start-large/.gitignore create mode 100644 examples/solid/start-large/.vscode/settings.json create mode 100644 examples/solid/start-large/package.json create mode 100644 examples/solid/start-large/postcss.config.mjs create mode 100644 examples/solid/start-large/src/createRoutes.mjs create mode 100644 examples/solid/start-large/src/routeTree.gen.ts create mode 100644 examples/solid/start-large/src/router.tsx create mode 100644 examples/solid/start-large/src/routes/__root.tsx create mode 100644 examples/solid/start-large/src/routes/absolute.tsx create mode 100644 examples/solid/start-large/src/routes/index.tsx create mode 100644 examples/solid/start-large/src/routes/linkProps.tsx create mode 100644 examples/solid/start-large/src/routes/params/$paramsPlaceholder.tsx create mode 100644 examples/solid/start-large/src/routes/params/route.tsx create mode 100644 examples/solid/start-large/src/routes/relative.tsx create mode 100644 examples/solid/start-large/src/routes/search/route.tsx create mode 100644 examples/solid/start-large/src/routes/search/searchPlaceholder.tsx create mode 100644 examples/solid/start-large/src/styles.css create mode 100644 examples/solid/start-large/src/typePrimitives.tsx create mode 100644 examples/solid/start-large/tsconfig.json create mode 100644 examples/solid/start-large/vite.config.ts diff --git a/examples/solid/start-large/.gitignore b/examples/solid/start-large/.gitignore new file mode 100644 index 00000000000..ca4ef70bc04 --- /dev/null +++ b/examples/solid/start-large/.gitignore @@ -0,0 +1,19 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local +(gen) +node_modules +package-lock.json +yarn.lock + +.DS_Store +.cache +.env +.vercel +.output +/build/ +/api/ +/server/build +/public/build \ No newline at end of file diff --git a/examples/solid/start-large/.vscode/settings.json b/examples/solid/start-large/.vscode/settings.json new file mode 100644 index 00000000000..00b5278e580 --- /dev/null +++ b/examples/solid/start-large/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.watcherExclude": { + "**/routeTree.gen.ts": true + }, + "search.exclude": { + "**/routeTree.gen.ts": true + }, + "files.readonlyInclude": { + "**/routeTree.gen.ts": true + } +} diff --git a/examples/solid/start-large/package.json b/examples/solid/start-large/package.json new file mode 100644 index 00000000000..ee72f27ff66 --- /dev/null +++ b/examples/solid/start-large/package.json @@ -0,0 +1,36 @@ +{ + "name": "tanstack-solid-start-example-large", + "private": true, + "sideEffects": false, + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build && tsc --noEmit", + "start": "vite start", + "gen": "node ./src/createRoutes.mjs", + "test:types": "tsc --extendedDiagnostics" + }, + "dependencies": { + "@tanstack/solid-query": "^5.90.0", + "@tanstack/solid-router": "^1.135.2", + "@tanstack/solid-router-devtools": "^1.135.2", + "@tanstack/solid-start": "^1.135.2", + "solid-js": "^1.9.10", + "redaxios": "^0.5.1", + "tailwind-merge": "^2.6.0", + "valibot": "^1.0.0-beta.15" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.1.15", + "@types/node": "^22.5.4", + "vite-plugin-solid": "^2.11.10", + "postcss": "^8.5.1", + "tailwindcss": "^4.1.15", + "typescript": "^5.7.2", + "vite": "^7.1.7", + "vite-tsconfig-paths": "^5.1.4" + }, + "keywords": [], + "author": "", + "license": "ISC" +} diff --git a/examples/solid/start-large/postcss.config.mjs b/examples/solid/start-large/postcss.config.mjs new file mode 100644 index 00000000000..a7f73a2d1d7 --- /dev/null +++ b/examples/solid/start-large/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + }, +} diff --git a/examples/solid/start-large/src/createRoutes.mjs b/examples/solid/start-large/src/createRoutes.mjs new file mode 100644 index 00000000000..c86294b699b --- /dev/null +++ b/examples/solid/start-large/src/createRoutes.mjs @@ -0,0 +1,49 @@ +import { readFile, writeFile, mkdir } from 'fs/promises' +import { existsSync } from 'fs' + +const length = 100 + +const main = async () => { + const absolute = (await readFile('./src/routes/absolute.tsx')).toString() + const relative = (await readFile('./src/routes/relative.tsx')).toString() + const searchRoute = ( + await readFile('./src/routes/search/route.tsx') + ).toString() + const search = ( + await readFile('./src/routes/search/searchPlaceholder.tsx') + ).toString() + const paramsRoute = ( + await readFile('./src/routes/params/route.tsx') + ).toString() + const params = await ( + await readFile('./src/routes/params/$paramsPlaceholder.tsx') + ).toString() + + if (!existsSync('./src/routes/(gen)')) { + await mkdir('./src/routes/(gen)') + } + + if (!existsSync('./src/routes/(gen)/search')) { + await mkdir('./src/routes/(gen)/search') + } + + if (!existsSync('./src/routes/(gen)/params')) { + await mkdir('./src/routes/(gen)/params') + } + + await writeFile('./src/routes/(gen)/search/route.tsx', searchRoute) + await writeFile('./src/routes/(gen)/params/route.tsx', paramsRoute) + + for (let y = 0; y < length; y = y + 1) { + const replacedAbsolute = absolute.replaceAll('/absolute', `/absolute${y}`) + const replacedRelative = relative.replaceAll('/relative', `/relative${y}`) + const replacedSearch = search.replaceAll('searchPlaceholder', `search${y}`) + const replacedParams = params.replaceAll('paramsPlaceholder', `param${y}`) + await writeFile(`./src/routes/(gen)/absolute${y}.tsx`, replacedAbsolute) + await writeFile(`./src/routes/(gen)/relative${y}.tsx`, replacedRelative) + await writeFile(`./src/routes/(gen)/search/search${y}.tsx`, replacedSearch) + await writeFile(`./src/routes/(gen)/params/$param${y}.tsx`, replacedParams) + } +} + +main() diff --git a/examples/solid/start-large/src/routeTree.gen.ts b/examples/solid/start-large/src/routeTree.gen.ts new file mode 100644 index 00000000000..3fb99e1aca4 --- /dev/null +++ b/examples/solid/start-large/src/routeTree.gen.ts @@ -0,0 +1,239 @@ +/* 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 RelativeRouteImport } from './routes/relative' +import { Route as LinkPropsRouteImport } from './routes/linkProps' +import { Route as AbsoluteRouteImport } from './routes/absolute' +import { Route as SearchRouteRouteImport } from './routes/search/route' +import { Route as ParamsRouteRouteImport } from './routes/params/route' +import { Route as IndexRouteImport } from './routes/index' +import { Route as SearchSearchPlaceholderRouteImport } from './routes/search/searchPlaceholder' +import { Route as ParamsParamsPlaceholderRouteImport } from './routes/params/$paramsPlaceholder' + +const RelativeRoute = RelativeRouteImport.update({ + id: '/relative', + path: '/relative', + getParentRoute: () => rootRouteImport, +} as any) +const LinkPropsRoute = LinkPropsRouteImport.update({ + id: '/linkProps', + path: '/linkProps', + getParentRoute: () => rootRouteImport, +} as any) +const AbsoluteRoute = AbsoluteRouteImport.update({ + id: '/absolute', + path: '/absolute', + getParentRoute: () => rootRouteImport, +} as any) +const SearchRouteRoute = SearchRouteRouteImport.update({ + id: '/search', + path: '/search', + getParentRoute: () => rootRouteImport, +} as any) +const ParamsRouteRoute = ParamsRouteRouteImport.update({ + id: '/params', + path: '/params', + getParentRoute: () => rootRouteImport, +} as any) +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) +const SearchSearchPlaceholderRoute = SearchSearchPlaceholderRouteImport.update({ + id: '/searchPlaceholder', + path: '/searchPlaceholder', + getParentRoute: () => SearchRouteRoute, +} as any) +const ParamsParamsPlaceholderRoute = ParamsParamsPlaceholderRouteImport.update({ + id: '/$paramsPlaceholder', + path: '/$paramsPlaceholder', + getParentRoute: () => ParamsRouteRoute, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute + '/params': typeof ParamsRouteRouteWithChildren + '/search': typeof SearchRouteRouteWithChildren + '/absolute': typeof AbsoluteRoute + '/linkProps': typeof LinkPropsRoute + '/relative': typeof RelativeRoute + '/params/$paramsPlaceholder': typeof ParamsParamsPlaceholderRoute + '/search/searchPlaceholder': typeof SearchSearchPlaceholderRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute + '/params': typeof ParamsRouteRouteWithChildren + '/search': typeof SearchRouteRouteWithChildren + '/absolute': typeof AbsoluteRoute + '/linkProps': typeof LinkPropsRoute + '/relative': typeof RelativeRoute + '/params/$paramsPlaceholder': typeof ParamsParamsPlaceholderRoute + '/search/searchPlaceholder': typeof SearchSearchPlaceholderRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute + '/params': typeof ParamsRouteRouteWithChildren + '/search': typeof SearchRouteRouteWithChildren + '/absolute': typeof AbsoluteRoute + '/linkProps': typeof LinkPropsRoute + '/relative': typeof RelativeRoute + '/params/$paramsPlaceholder': typeof ParamsParamsPlaceholderRoute + '/search/searchPlaceholder': typeof SearchSearchPlaceholderRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: + | '/' + | '/params' + | '/search' + | '/absolute' + | '/linkProps' + | '/relative' + | '/params/$paramsPlaceholder' + | '/search/searchPlaceholder' + fileRoutesByTo: FileRoutesByTo + to: + | '/' + | '/params' + | '/search' + | '/absolute' + | '/linkProps' + | '/relative' + | '/params/$paramsPlaceholder' + | '/search/searchPlaceholder' + id: + | '__root__' + | '/' + | '/params' + | '/search' + | '/absolute' + | '/linkProps' + | '/relative' + | '/params/$paramsPlaceholder' + | '/search/searchPlaceholder' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute + ParamsRouteRoute: typeof ParamsRouteRouteWithChildren + SearchRouteRoute: typeof SearchRouteRouteWithChildren + AbsoluteRoute: typeof AbsoluteRoute + LinkPropsRoute: typeof LinkPropsRoute + RelativeRoute: typeof RelativeRoute +} + +declare module '@tanstack/solid-router' { + interface FileRoutesByPath { + '/relative': { + id: '/relative' + path: '/relative' + fullPath: '/relative' + preLoaderRoute: typeof RelativeRouteImport + parentRoute: typeof rootRouteImport + } + '/linkProps': { + id: '/linkProps' + path: '/linkProps' + fullPath: '/linkProps' + preLoaderRoute: typeof LinkPropsRouteImport + parentRoute: typeof rootRouteImport + } + '/absolute': { + id: '/absolute' + path: '/absolute' + fullPath: '/absolute' + preLoaderRoute: typeof AbsoluteRouteImport + parentRoute: typeof rootRouteImport + } + '/search': { + id: '/search' + path: '/search' + fullPath: '/search' + preLoaderRoute: typeof SearchRouteRouteImport + parentRoute: typeof rootRouteImport + } + '/params': { + id: '/params' + path: '/params' + fullPath: '/params' + preLoaderRoute: typeof ParamsRouteRouteImport + parentRoute: typeof rootRouteImport + } + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + '/search/searchPlaceholder': { + id: '/search/searchPlaceholder' + path: '/searchPlaceholder' + fullPath: '/search/searchPlaceholder' + preLoaderRoute: typeof SearchSearchPlaceholderRouteImport + parentRoute: typeof SearchRouteRoute + } + '/params/$paramsPlaceholder': { + id: '/params/$paramsPlaceholder' + path: '/$paramsPlaceholder' + fullPath: '/params/$paramsPlaceholder' + preLoaderRoute: typeof ParamsParamsPlaceholderRouteImport + parentRoute: typeof ParamsRouteRoute + } + } +} + +interface ParamsRouteRouteChildren { + ParamsParamsPlaceholderRoute: typeof ParamsParamsPlaceholderRoute +} + +const ParamsRouteRouteChildren: ParamsRouteRouteChildren = { + ParamsParamsPlaceholderRoute: ParamsParamsPlaceholderRoute, +} + +const ParamsRouteRouteWithChildren = ParamsRouteRoute._addFileChildren( + ParamsRouteRouteChildren, +) + +interface SearchRouteRouteChildren { + SearchSearchPlaceholderRoute: typeof SearchSearchPlaceholderRoute +} + +const SearchRouteRouteChildren: SearchRouteRouteChildren = { + SearchSearchPlaceholderRoute: SearchSearchPlaceholderRoute, +} + +const SearchRouteRouteWithChildren = SearchRouteRoute._addFileChildren( + SearchRouteRouteChildren, +) + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + ParamsRouteRoute: ParamsRouteRouteWithChildren, + SearchRouteRoute: SearchRouteRouteWithChildren, + AbsoluteRoute: AbsoluteRoute, + LinkPropsRoute: LinkPropsRoute, + RelativeRoute: RelativeRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() + +import type { getRouter } from './router.tsx' +import type { createStart } from '@tanstack/solid-start' +declare module '@tanstack/solid-start' { + interface Register { + ssr: true + router: Awaited> + } +} diff --git a/examples/solid/start-large/src/router.tsx b/examples/solid/start-large/src/router.tsx new file mode 100644 index 00000000000..60564218b94 --- /dev/null +++ b/examples/solid/start-large/src/router.tsx @@ -0,0 +1,15 @@ +import { createRouter } from '@tanstack/solid-router' +import { QueryClient } from '@tanstack/solid-query' +import { routeTree } from './routeTree.gen' + +export function getRouter() { + const queryClient = new QueryClient() + const router = createRouter({ + routeTree, + context: { + queryClient: queryClient, + }, + }) + + return router +} diff --git a/examples/solid/start-large/src/routes/__root.tsx b/examples/solid/start-large/src/routes/__root.tsx new file mode 100644 index 00000000000..d934db5cf1f --- /dev/null +++ b/examples/solid/start-large/src/routes/__root.tsx @@ -0,0 +1,56 @@ +// src/routes/__root.tsx +import { + HeadContent, + Outlet, + Scripts, + createRootRouteWithContext, +} from '@tanstack/solid-router' +import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools' +import type { QueryClient } from '@tanstack/solid-query' +import type { JSX } from 'solid-js' + +export interface Context { + queryClient: QueryClient +} + +export const Route = createRootRouteWithContext()({ + head: () => ({ + links: [{ rel: 'stylesheet' }], + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + { + title: 'TanStack Start Starter', + }, + ], + }), + component: RootComponent, +}) + +function RootComponent() { + return ( + + + + ) +} + +function RootDocument({ children }: Readonly<{ children: JSX.Element }>) { + return ( + + + + + + {children} + + + + + ) +} diff --git a/examples/solid/start-large/src/routes/absolute.tsx b/examples/solid/start-large/src/routes/absolute.tsx new file mode 100644 index 00000000000..f9ddebc65a8 --- /dev/null +++ b/examples/solid/start-large/src/routes/absolute.tsx @@ -0,0 +1,18 @@ +import { Link, createFileRoute } from '@tanstack/solid-router' + +export const Route = createFileRoute('/absolute')({ + component: AbsoluteComponent, +}) + +function AbsoluteComponent() { + return ( +
+ + Absolute + +
+ ) +} diff --git a/examples/solid/start-large/src/routes/index.tsx b/examples/solid/start-large/src/routes/index.tsx new file mode 100644 index 00000000000..bdfb4c76768 --- /dev/null +++ b/examples/solid/start-large/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/examples/solid/start-large/src/routes/linkProps.tsx b/examples/solid/start-large/src/routes/linkProps.tsx new file mode 100644 index 00000000000..ed8a8e7e3e9 --- /dev/null +++ b/examples/solid/start-large/src/routes/linkProps.tsx @@ -0,0 +1,72 @@ +import { Link, createFileRoute, linkOptions } from '@tanstack/solid-router' +import { + ListItems, + MyLink, + customRedirect, + useCustomNavigate, +} from '~/typePrimitives' + +export const Route = createFileRoute('/linkProps')({ + component: LinkPropsPage, + loader: () => { + throw customRedirect({ + to: '/search/searchPlaceholder', + search: { + searchPlaceholder: 'searchPlaceholder', + rootSearch: 0, + page: 0, + offset: 0, + search: 'hi', + }, + }) + }, +}) + +function LinkPropsPage() { + useCustomNavigate({ + to: '/search/searchPlaceholder', + search: { + searchPlaceholder: 'searchPlaceholder', + rootSearch: 0, + page: 0, + offset: 0, + search: 'hi', + }, + }) + + const linkProps = linkOptions({ + to: '/absolute', + }) + + return ( + <> + + + + + ) +} diff --git a/examples/solid/start-large/src/routes/params/$paramsPlaceholder.tsx b/examples/solid/start-large/src/routes/params/$paramsPlaceholder.tsx new file mode 100644 index 00000000000..d7a62860e5d --- /dev/null +++ b/examples/solid/start-large/src/routes/params/$paramsPlaceholder.tsx @@ -0,0 +1,76 @@ +import { Link, createFileRoute } from '@tanstack/solid-router' +import * as v from 'valibot' +import { queryOptions } from '@tanstack/solid-query' +import { createMiddleware, createServerFn } from '@tanstack/solid-start' + +const params = v.object({ + oneParamsPlaceholder: v.literal('oneParamsPlaceholder'), + twoParamsPlaceholder: v.literal('twoParamsPlaceholder'), + threeParamsPlaceholder: v.literal('threeParamsPlaceholder'), +}) + +const loaderResult = v.object({ + params, +}) + +const middleware = createMiddleware({ type: 'function' }) + .inputValidator(params) + .client(({ next }) => { + const context = { client: { paramsPlaceholder: 'paramsPlaceholder' } } + return next({ + context, + sendContext: context, + }) + }) + .server(({ next }) => { + const context = { server: { paramsPlaceholder: 'paramsPlaceholder' } } + return next({ + context, + sendContext: context, + }) + }) + +const fn = createServerFn() + .middleware([middleware]) + .handler(() => { + return v.parse(loaderResult, {}) + }) + +const paramsQueryOptions = queryOptions({ + queryKey: ['paramsPlaceholder'], + queryFn: () => { + return v.parse(loaderResult, {}) + }, +}) + +export const Route = createFileRoute('/params/$paramsPlaceholder')({ + component: ParamsComponent, + context: () => ({ + paramsQueryOptions: queryOptions({ + queryKey: ['paramsPlaceholder'], + queryFn: async () => + await fn({ + data: { + oneParamsPlaceholder: 'oneParamsPlaceholder', + twoParamsPlaceholder: 'twoParamsPlaceholder', + threeParamsPlaceholder: 'threeParamsPlaceholder', + }, + }), + }), + }), + loader: (opts) => + opts.context.queryClient.ensureQueryData(paramsQueryOptions), +}) + +function ParamsComponent() { + return ( +
+ +
+ ) +} diff --git a/examples/solid/start-large/src/routes/params/route.tsx b/examples/solid/start-large/src/routes/params/route.tsx new file mode 100644 index 00000000000..2177bb397a0 --- /dev/null +++ b/examples/solid/start-large/src/routes/params/route.tsx @@ -0,0 +1,5 @@ +import { createFileRoute } from '@tanstack/solid-router' + +export const Route = createFileRoute('/params')({ + component: () =>
Hello /params!
, +}) diff --git a/examples/solid/start-large/src/routes/relative.tsx b/examples/solid/start-large/src/routes/relative.tsx new file mode 100644 index 00000000000..d14cd447bc9 --- /dev/null +++ b/examples/solid/start-large/src/routes/relative.tsx @@ -0,0 +1,19 @@ +import { Link, createFileRoute } from '@tanstack/solid-router' + +export const Route = createFileRoute('/relative')({ + component: RelativeComponent, +}) + +function RelativeComponent() { + return ( +
+ + Relative + +
+ ) +} diff --git a/examples/solid/start-large/src/routes/search/route.tsx b/examples/solid/start-large/src/routes/search/route.tsx new file mode 100644 index 00000000000..f4fa71df826 --- /dev/null +++ b/examples/solid/start-large/src/routes/search/route.tsx @@ -0,0 +1,11 @@ +import { createFileRoute } from '@tanstack/solid-router' +import * as v from 'valibot' + +const search = v.object({ + rootSearch: v.number(), +}) + +export const Route = createFileRoute('/search')({ + component: () =>
Hello /search!
, + validateSearch: search, +}) diff --git a/examples/solid/start-large/src/routes/search/searchPlaceholder.tsx b/examples/solid/start-large/src/routes/search/searchPlaceholder.tsx new file mode 100644 index 00000000000..0fa857d29c8 --- /dev/null +++ b/examples/solid/start-large/src/routes/search/searchPlaceholder.tsx @@ -0,0 +1,89 @@ +import { Link, createFileRoute } from '@tanstack/solid-router' +import * as v from 'valibot' +import { queryOptions } from '@tanstack/solid-query' +import { createMiddleware, createServerFn } from '@tanstack/solid-start' + +const search = v.object({ + searchPlaceholder: v.literal('searchPlaceholder'), + page: v.number(), + offset: v.number(), + search: v.string(), +}) + +const loaderResult = v.object({ + searchPlaceholder: v.number(), +}) + +const middleware = createMiddleware({ type: 'function' }) + .inputValidator(search) + .client(({ next }) => { + const context = { client: { searchPlaceholder: 'searchPlaceholder' } } + return next({ + context, + sendContext: context, + }) + }) + .server(({ next }) => { + const context = { server: { searchPlaceholder: 'searchPlaceholder' } } + return next({ + context, + sendContext: context, + }) + }) + +const fn = createServerFn() + .middleware([middleware]) + .handler(() => { + const result = v.parse(loaderResult, { + searchPlaceholder: 0, + }) + return result + }) + +export const Route = createFileRoute('/search/searchPlaceholder')({ + server: { + handlers: { + GET: () => { + return new Response('searchPlaceholder') + }, + }, + }, + component: SearchComponent, + validateSearch: search, + loaderDeps: ({ search }) => ({ search }), + context: (ctx) => ({ + searchQueryOptions: queryOptions({ + queryKey: ['searchPlaceholder'], + queryFn: () => fn({ data: ctx.deps.search }), + }), + }), + loader: async (opts) => { + const search = await opts.context.queryClient.ensureQueryData( + opts.context.searchQueryOptions, + ) + + return { + search, + } + }, +}) + +function SearchComponent() { + return ( +
+ + Search + +
+ ) +} diff --git a/examples/solid/start-large/src/styles.css b/examples/solid/start-large/src/styles.css new file mode 100644 index 00000000000..c36c737cd46 --- /dev/null +++ b/examples/solid/start-large/src/styles.css @@ -0,0 +1,30 @@ +@import 'tailwindcss'; + +@layer base { + *, + ::after, + ::before, + ::backdrop, + ::file-selector-button { + border-color: var(--color-gray-200, currentcolor); + } +} + +@layer base { + html { + color-scheme: light dark; + } + + * { + @apply border-gray-200 dark:border-gray-800; + } + + html, + body { + @apply text-gray-900 bg-gray-50 dark:bg-gray-950 dark:text-gray-200; + } + + .using-mouse * { + outline: none !important; + } +} diff --git a/examples/solid/start-large/src/typePrimitives.tsx b/examples/solid/start-large/src/typePrimitives.tsx new file mode 100644 index 00000000000..6d2d3316458 --- /dev/null +++ b/examples/solid/start-large/src/typePrimitives.tsx @@ -0,0 +1,50 @@ +import { Link, redirect, useNavigate } from '@tanstack/solid-router' +import type { + RegisteredRouter, + ValidateFromPath, + ValidateLinkOptions, + ValidateLinkOptionsArray, + ValidateNavigateOptions, + ValidateRedirectOptions, +} from '@tanstack/solid-router' +import type { JSX } from 'solid-js' + +export function customRedirect( + options: ValidateRedirectOptions, +): void +export function customRedirect(options: ValidateRedirectOptions): void { + throw redirect(options) +} + +export function useCustomNavigate( + options: ValidateNavigateOptions, +): void +export function useCustomNavigate(options: ValidateNavigateOptions): void { + const navigate = useNavigate() + navigate(options) +} + +export function MyLink( + options: ValidateLinkOptions, +): JSX.Element +export function MyLink(options: ValidateLinkOptions) { + return +} + +export interface ListItemsProps< + TRouter extends RegisteredRouter = RegisteredRouter, + TOptions extends ReadonlyArray = ReadonlyArray, + TFrom extends string = string, +> { + from: ValidateFromPath + items: ValidateLinkOptionsArray +} + +export function ListItems< + TRouter extends RegisteredRouter, + TOptions extends ReadonlyArray, + TFrom extends string, +>(options: ListItemsProps): JSX.Element +export function ListItems(options: ListItemsProps) { + return options.items.map((item) => ) +} diff --git a/examples/solid/start-large/tsconfig.json b/examples/solid/start-large/tsconfig.json new file mode 100644 index 00000000000..a40235b863f --- /dev/null +++ b/examples/solid/start-large/tsconfig.json @@ -0,0 +1,23 @@ +{ + "include": ["**/*.ts", "**/*.tsx"], + "compilerOptions": { + "strict": true, + "esModuleInterop": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["DOM", "DOM.Iterable", "ES2022"], + "isolatedModules": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "target": "ES2022", + "allowJs": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + "paths": { + "~/*": ["./src/*"] + }, + "noEmit": true + } +} diff --git a/examples/solid/start-large/vite.config.ts b/examples/solid/start-large/vite.config.ts new file mode 100644 index 00000000000..27a27a7b5a5 --- /dev/null +++ b/examples/solid/start-large/vite.config.ts @@ -0,0 +1,17 @@ +import { tanstackStart } from '@tanstack/solid-start/plugin/vite' +import { defineConfig } from 'vite' +import tsConfigPaths from 'vite-tsconfig-paths' +import viteSolid from 'vite-plugin-solid' + +export default defineConfig({ + server: { + port: 3000, + }, + plugins: [ + tsConfigPaths({ + projects: ['./tsconfig.json'], + }), + tanstackStart(), + viteSolid({ ssr: true }), + ], +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fade56178ec..c42196d18e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8432,6 +8432,58 @@ importers: specifier: ^5.1.4 version: 5.1.4(typescript@5.9.2)(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)) + examples/solid/start-large: + dependencies: + '@tanstack/solid-query': + specifier: ^5.90.0 + version: 5.90.9(solid-js@1.9.10) + '@tanstack/solid-router': + specifier: ^1.135.2 + version: link:../../../packages/solid-router + '@tanstack/solid-router-devtools': + specifier: workspace:^ + version: link:../../../packages/solid-router-devtools + '@tanstack/solid-start': + specifier: workspace:* + version: link:../../../packages/solid-start + redaxios: + specifier: ^0.5.1 + version: 0.5.1 + solid-js: + specifier: 1.9.10 + version: 1.9.10 + tailwind-merge: + specifier: ^2.6.0 + version: 2.6.0 + valibot: + specifier: ^1.0.0-beta.15 + version: 1.0.0-beta.15(typescript@5.9.2) + devDependencies: + '@tailwindcss/postcss': + specifier: ^4.1.15 + version: 4.1.15 + '@types/node': + specifier: 22.10.2 + version: 22.10.2 + postcss: + specifier: ^8.5.1 + version: 8.5.6 + tailwindcss: + specifier: ^4.1.15 + version: 4.1.17 + typescript: + specifier: ^5.7.2 + version: 5.9.2 + 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.10)(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)) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.2)(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)) + examples/solid/start-streaming-data-from-server-functions: dependencies: '@tanstack/solid-router': From 08deea1d6003bed3acfbc871ebac307ec77d5d57 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 19:42:57 +0000 Subject: [PATCH 2/2] ci: apply automated fixes --- examples/solid/start-large/src/routes/absolute.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/solid/start-large/src/routes/absolute.tsx b/examples/solid/start-large/src/routes/absolute.tsx index f9ddebc65a8..d4b44ed0dc7 100644 --- a/examples/solid/start-large/src/routes/absolute.tsx +++ b/examples/solid/start-large/src/routes/absolute.tsx @@ -7,10 +7,7 @@ export const Route = createFileRoute('/absolute')({ function AbsoluteComponent() { return (
- + Absolute