diff --git a/docs/framework/react/start/getting-started.md b/docs/framework/react/start/getting-started.md index 9ad16980ca..8daa36569d 100644 --- a/docs/framework/react/start/getting-started.md +++ b/docs/framework/react/start/getting-started.md @@ -199,18 +199,20 @@ import { Meta, Scripts } from '@tanstack/start' import type { ReactNode } from 'react' export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - { - title: 'TanStack Start Starter', - }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + { + title: 'TanStack Start Starter', + }, + ], + }), component: RootComponent, }) diff --git a/e2e/react-router/basic-esbuild-file-based/src/routes/posts.$postId.tsx b/e2e/react-router/basic-esbuild-file-based/src/routes/posts.$postId.tsx index febb02ab2f..cded91ef96 100644 --- a/e2e/react-router/basic-esbuild-file-based/src/routes/posts.$postId.tsx +++ b/e2e/react-router/basic-esbuild-file-based/src/routes/posts.$postId.tsx @@ -5,7 +5,7 @@ import type { ErrorComponentProps } from '@tanstack/react-router' export const Route = createFileRoute('/posts/$postId')({ loader: async ({ params: { postId } }) => fetchPost(postId), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, notFoundComponent: () => { return

Post not found

}, diff --git a/e2e/react-router/basic-file-based/src/routes/posts.$postId.tsx b/e2e/react-router/basic-file-based/src/routes/posts.$postId.tsx index febb02ab2f..cded91ef96 100644 --- a/e2e/react-router/basic-file-based/src/routes/posts.$postId.tsx +++ b/e2e/react-router/basic-file-based/src/routes/posts.$postId.tsx @@ -5,7 +5,7 @@ import type { ErrorComponentProps } from '@tanstack/react-router' export const Route = createFileRoute('/posts/$postId')({ loader: async ({ params: { postId } }) => fetchPost(postId), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, notFoundComponent: () => { return

Post not found

}, diff --git a/e2e/react-router/basic-react-query-file-based/src/routes/posts.$postId.tsx b/e2e/react-router/basic-react-query-file-based/src/routes/posts.$postId.tsx index 78455fdcdf..4cf6beca88 100644 --- a/e2e/react-router/basic-react-query-file-based/src/routes/posts.$postId.tsx +++ b/e2e/react-router/basic-react-query-file-based/src/routes/posts.$postId.tsx @@ -20,7 +20,7 @@ export const Route = createFileRoute('/posts/$postId')({ component: PostComponent, }) -export function PostErrorComponent({ error, reset }: ErrorComponentProps) { +export function PostErrorComponent({ error }: ErrorComponentProps) { const router = useRouter() if (error instanceof PostNotFoundError) { return
{error.message}
diff --git a/e2e/react-router/basic-react-query/src/main.tsx b/e2e/react-router/basic-react-query/src/main.tsx index a5455491c0..30abb90ffc 100644 --- a/e2e/react-router/basic-react-query/src/main.tsx +++ b/e2e/react-router/basic-react-query/src/main.tsx @@ -2,7 +2,6 @@ import React from 'react' import ReactDOM from 'react-dom/client' import { ErrorComponent, - type ErrorComponentProps, Link, Outlet, RouterProvider, @@ -20,6 +19,7 @@ import { useSuspenseQuery, } from '@tanstack/react-query' import { NotFoundError, postQueryOptions, postsQueryOptions } from './posts' +import type { ErrorComponentProps } from '@tanstack/react-router' const rootRoute = createRootRouteWithContext<{ queryClient: QueryClient diff --git a/e2e/react-router/basic-scroll-restoration/src/main.tsx b/e2e/react-router/basic-scroll-restoration/src/main.tsx index 8475f4c3f5..d0d22cc81c 100644 --- a/e2e/react-router/basic-scroll-restoration/src/main.tsx +++ b/e2e/react-router/basic-scroll-restoration/src/main.tsx @@ -214,7 +214,7 @@ const router = createRouter({ routeTree, defaultPreload: 'intent' }) declare global { interface Window { - invokeOrders: string[] + invokeOrders: Array } } window.invokeOrders = [] diff --git a/e2e/react-router/basic-virtual-file-based/src/routes/file-based-subtree/hello/index.tsx b/e2e/react-router/basic-virtual-file-based/src/routes/file-based-subtree/hello/index.tsx index 7a6d5e3bd3..c7417e5eeb 100644 --- a/e2e/react-router/basic-virtual-file-based/src/routes/file-based-subtree/hello/index.tsx +++ b/e2e/react-router/basic-virtual-file-based/src/routes/file-based-subtree/hello/index.tsx @@ -1,4 +1,4 @@ -import { Link, createFileRoute } from '@tanstack/react-router' +import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/classic/hello/')({ component: () =>
This is the index
, diff --git a/e2e/react-router/basic/src/main.tsx b/e2e/react-router/basic/src/main.tsx index f75bdb8629..873374a010 100644 --- a/e2e/react-router/basic/src/main.tsx +++ b/e2e/react-router/basic/src/main.tsx @@ -1,7 +1,6 @@ import ReactDOM from 'react-dom/client' import { ErrorComponent, - type ErrorComponentProps, Link, Outlet, RouterProvider, @@ -11,6 +10,7 @@ import { } from '@tanstack/react-router' import { TanStackRouterDevtools } from '@tanstack/router-devtools' import { NotFoundError, fetchPost, fetchPosts } from './posts' +import type { ErrorComponentProps } from '@tanstack/react-router' const rootRoute = createRootRoute({ component: RootComponent, diff --git a/e2e/start/basic-auth/app/client.tsx b/e2e/start/basic-auth/app/client.tsx index b887037fc4..3bfe090a3e 100644 --- a/e2e/start/basic-auth/app/client.tsx +++ b/e2e/start/basic-auth/app/client.tsx @@ -1,3 +1,4 @@ +/// import { hydrateRoot } from 'react-dom/client' import { StartClient } from '@tanstack/start' import { createRouter } from './router' diff --git a/e2e/start/basic-auth/app/components/DefaultCatchBoundary.tsx b/e2e/start/basic-auth/app/components/DefaultCatchBoundary.tsx index f0ce51dc57..15f316681c 100644 --- a/e2e/start/basic-auth/app/components/DefaultCatchBoundary.tsx +++ b/e2e/start/basic-auth/app/components/DefaultCatchBoundary.tsx @@ -1,11 +1,11 @@ import { ErrorComponent, - ErrorComponentProps, Link, rootRouteId, useMatch, useRouter, } from '@tanstack/react-router' +import type { ErrorComponentProps } from '@tanstack/react-router' export function DefaultCatchBoundary({ error }: ErrorComponentProps) { const router = useRouter() diff --git a/e2e/start/basic-auth/app/routes/__root.tsx b/e2e/start/basic-auth/app/routes/__root.tsx index 3ab9c663b8..d5399b0962 100644 --- a/e2e/start/basic-auth/app/routes/__root.tsx +++ b/e2e/start/basic-auth/app/routes/__root.tsx @@ -7,6 +7,7 @@ import { import { TanStackRouterDevtools } from '@tanstack/router-devtools' import { Meta, Scripts, createServerFn } from '@tanstack/start' import * as React from 'react' + import { DefaultCatchBoundary } from '~/components/DefaultCatchBoundary.js' import { NotFound } from '~/components/NotFound.js' import appCss from '~/styles/app.css?url' @@ -27,42 +28,44 @@ const fetchUser = createServerFn({ method: 'GET' }).handler(async () => { }) export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), beforeLoad: async () => { const user = await fetchUser() diff --git a/e2e/start/basic-auth/app/routes/_authed.tsx b/e2e/start/basic-auth/app/routes/_authed.tsx index 35fc3cbc63..d8a208d3c1 100644 --- a/e2e/start/basic-auth/app/routes/_authed.tsx +++ b/e2e/start/basic-auth/app/routes/_authed.tsx @@ -1,5 +1,6 @@ import { createFileRoute } from '@tanstack/react-router' import { createServerFn } from '@tanstack/start' + import { hashPassword, prismaClient } from '~/utils/prisma' import { Login } from '~/components/Login' import { useAppSession } from '~/utils/session' diff --git a/e2e/start/basic-auth/app/routes/_authed/posts.$postId.tsx b/e2e/start/basic-auth/app/routes/_authed/posts.$postId.tsx index e4680c6070..27296b9658 100644 --- a/e2e/start/basic-auth/app/routes/_authed/posts.$postId.tsx +++ b/e2e/start/basic-auth/app/routes/_authed/posts.$postId.tsx @@ -1,11 +1,12 @@ import { ErrorComponent, createFileRoute } from '@tanstack/react-router' import type { ErrorComponentProps } from '@tanstack/react-router' + import { NotFound } from '~/components/NotFound.js' import { fetchPost } from '~/utils/posts.js' export const Route = createFileRoute('/_authed/posts/$postId')({ loader: ({ params: { postId } }) => fetchPost({ data: postId }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostComponent, notFoundComponent: () => { return Post not found diff --git a/e2e/start/basic-auth/app/routes/_authed/posts.tsx b/e2e/start/basic-auth/app/routes/_authed/posts.tsx index 86c8ef4138..c01f12c49a 100644 --- a/e2e/start/basic-auth/app/routes/_authed/posts.tsx +++ b/e2e/start/basic-auth/app/routes/_authed/posts.tsx @@ -1,4 +1,5 @@ import { Link, Outlet, createFileRoute } from '@tanstack/react-router' + import { fetchPosts } from '~/utils/posts.js' export const Route = createFileRoute('/_authed/posts')({ diff --git a/e2e/start/basic-auth/app/routes/login.tsx b/e2e/start/basic-auth/app/routes/login.tsx index 03ced20832..19dc34a439 100644 --- a/e2e/start/basic-auth/app/routes/login.tsx +++ b/e2e/start/basic-auth/app/routes/login.tsx @@ -1,4 +1,5 @@ import { createFileRoute } from '@tanstack/react-router' + import { Login } from '~/components/Login' export const Route = createFileRoute('/login')({ diff --git a/e2e/start/basic-auth/app/routes/logout.tsx b/e2e/start/basic-auth/app/routes/logout.tsx index 10e35ca0a3..a62168476c 100644 --- a/e2e/start/basic-auth/app/routes/logout.tsx +++ b/e2e/start/basic-auth/app/routes/logout.tsx @@ -1,5 +1,6 @@ import { createFileRoute, redirect } from '@tanstack/react-router' import { createServerFn } from '@tanstack/start' + import { useAppSession } from '~/utils/session' const logoutFn = createServerFn({ method: 'POST' }).handler(async () => { diff --git a/e2e/start/basic-react-query/app/client.tsx b/e2e/start/basic-react-query/app/client.tsx index b887037fc4..3bfe090a3e 100644 --- a/e2e/start/basic-react-query/app/client.tsx +++ b/e2e/start/basic-react-query/app/client.tsx @@ -1,3 +1,4 @@ +/// import { hydrateRoot } from 'react-dom/client' import { StartClient } from '@tanstack/start' import { createRouter } from './router' diff --git a/e2e/start/basic-react-query/app/components/DefaultCatchBoundary.tsx b/e2e/start/basic-react-query/app/components/DefaultCatchBoundary.tsx index f0ce51dc57..15f316681c 100644 --- a/e2e/start/basic-react-query/app/components/DefaultCatchBoundary.tsx +++ b/e2e/start/basic-react-query/app/components/DefaultCatchBoundary.tsx @@ -1,11 +1,11 @@ import { ErrorComponent, - ErrorComponentProps, Link, rootRouteId, useMatch, useRouter, } from '@tanstack/react-router' +import type { ErrorComponentProps } from '@tanstack/react-router' export function DefaultCatchBoundary({ error }: ErrorComponentProps) { const router = useRouter() diff --git a/e2e/start/basic-react-query/app/routes/__root.tsx b/e2e/start/basic-react-query/app/routes/__root.tsx index c4a2301627..c916cbeda5 100644 --- a/e2e/start/basic-react-query/app/routes/__root.tsx +++ b/e2e/start/basic-react-query/app/routes/__root.tsx @@ -11,49 +11,50 @@ import * as React from 'react' import type { QueryClient } from '@tanstack/react-query' import { DefaultCatchBoundary } from '~/components/DefaultCatchBoundary' import { NotFound } from '~/components/NotFound' -// @ts-expect-error import appCss from '~/styles/app.css?url' import { seo } from '~/utils/seo' export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), errorComponent: (props) => { return ( diff --git a/e2e/start/basic-react-query/app/routes/posts.$postId.tsx b/e2e/start/basic-react-query/app/routes/posts.$postId.tsx index 546e3d2795..16a6bf29aa 100644 --- a/e2e/start/basic-react-query/app/routes/posts.$postId.tsx +++ b/e2e/start/basic-react-query/app/routes/posts.$postId.tsx @@ -1,7 +1,8 @@ import { ErrorComponent, Link, createFileRoute } from '@tanstack/react-router' import { useSuspenseQuery } from '@tanstack/react-query' -import { postQueryOptions } from '../utils/posts' import type { ErrorComponentProps } from '@tanstack/react-router' + +import { postQueryOptions } from '~/utils/posts' import { NotFound } from '~/components/NotFound' export const Route = createFileRoute('/posts/$postId')({ @@ -14,12 +15,10 @@ export const Route = createFileRoute('/posts/$postId')({ title: data.title, } }, - meta: ({ loaderData }) => [ - { - title: loaderData.title, - }, - ], - errorComponent: PostErrorComponent as any, + head: ({ loaderData }) => ({ + meta: loaderData ? [{ title: loaderData.title }] : undefined, + }), + errorComponent: PostErrorComponent, notFoundComponent: () => { return Post not found }, diff --git a/e2e/start/basic-react-query/app/routes/posts.tsx b/e2e/start/basic-react-query/app/routes/posts.tsx index 64600d15c4..3f678ed1f1 100644 --- a/e2e/start/basic-react-query/app/routes/posts.tsx +++ b/e2e/start/basic-react-query/app/routes/posts.tsx @@ -1,12 +1,13 @@ import { useSuspenseQuery } from '@tanstack/react-query' import { Link, Outlet, createFileRoute } from '@tanstack/react-router' -import { postsQueryOptions } from '../utils/posts' + +import { postsQueryOptions } from '~/utils/posts' export const Route = createFileRoute('/posts')({ loader: async ({ context }) => { await context.queryClient.ensureQueryData(postsQueryOptions()) }, - meta: () => [{ title: 'Posts' }], + head: () => ({ meta: [{ title: 'Posts' }] }), component: PostsComponent, }) diff --git a/e2e/start/basic-react-query/app/routes/posts_.$postId.deep.tsx b/e2e/start/basic-react-query/app/routes/posts_.$postId.deep.tsx index 219ba4771b..33f6475a55 100644 --- a/e2e/start/basic-react-query/app/routes/posts_.$postId.deep.tsx +++ b/e2e/start/basic-react-query/app/routes/posts_.$postId.deep.tsx @@ -13,12 +13,10 @@ export const Route = createFileRoute('/posts_/$postId/deep')({ title: data.title, } }, - meta: ({ loaderData }) => [ - { - title: loaderData.title, - }, - ], - errorComponent: PostErrorComponent as any, + head: ({ loaderData }) => ({ + meta: loaderData ? [{ title: loaderData.title }] : undefined, + }), + errorComponent: PostErrorComponent, component: PostDeepComponent, }) diff --git a/e2e/start/basic-react-query/app/routes/users.$userId.tsx b/e2e/start/basic-react-query/app/routes/users.$userId.tsx index 0750a01568..656fb6dbb8 100644 --- a/e2e/start/basic-react-query/app/routes/users.$userId.tsx +++ b/e2e/start/basic-react-query/app/routes/users.$userId.tsx @@ -1,6 +1,7 @@ import { useSuspenseQuery } from '@tanstack/react-query' import { ErrorComponent, createFileRoute } from '@tanstack/react-router' import type { ErrorComponentProps } from '@tanstack/react-router' + import { NotFound } from '~/components/NotFound' import { userQueryOptions } from '~/utils/users' diff --git a/e2e/start/basic-react-query/app/routes/users.tsx b/e2e/start/basic-react-query/app/routes/users.tsx index 2f3c72cb7b..1b56bb9890 100644 --- a/e2e/start/basic-react-query/app/routes/users.tsx +++ b/e2e/start/basic-react-query/app/routes/users.tsx @@ -1,6 +1,7 @@ import { useSuspenseQuery } from '@tanstack/react-query' import { Link, Outlet, createFileRoute } from '@tanstack/react-router' -import { usersQueryOptions } from '../utils/users' + +import { usersQueryOptions } from '~/utils/users' export const Route = createFileRoute('/users')({ loader: async ({ context }) => { diff --git a/e2e/start/basic-rsc/app/client.tsx b/e2e/start/basic-rsc/app/client.tsx index b887037fc4..3bfe090a3e 100644 --- a/e2e/start/basic-rsc/app/client.tsx +++ b/e2e/start/basic-rsc/app/client.tsx @@ -1,3 +1,4 @@ +/// import { hydrateRoot } from 'react-dom/client' import { StartClient } from '@tanstack/start' import { createRouter } from './router' diff --git a/e2e/start/basic-rsc/app/components/DefaultCatchBoundary.tsx b/e2e/start/basic-rsc/app/components/DefaultCatchBoundary.tsx index f0ce51dc57..15f316681c 100644 --- a/e2e/start/basic-rsc/app/components/DefaultCatchBoundary.tsx +++ b/e2e/start/basic-rsc/app/components/DefaultCatchBoundary.tsx @@ -1,11 +1,11 @@ import { ErrorComponent, - ErrorComponentProps, Link, rootRouteId, useMatch, useRouter, } from '@tanstack/react-router' +import type { ErrorComponentProps } from '@tanstack/react-router' export function DefaultCatchBoundary({ error }: ErrorComponentProps) { const router = useRouter() diff --git a/e2e/start/basic-rsc/app/routes/__root.tsx b/e2e/start/basic-rsc/app/routes/__root.tsx index a938538aea..2e19225490 100644 --- a/e2e/start/basic-rsc/app/routes/__root.tsx +++ b/e2e/start/basic-rsc/app/routes/__root.tsx @@ -13,42 +13,44 @@ import appCss from '~/styles/app.css?url' import { seo } from '~/utils/seo' export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), errorComponent: (props) => { return ( diff --git a/e2e/start/basic-rsc/app/routes/posts.$postId.tsx b/e2e/start/basic-rsc/app/routes/posts.$postId.tsx index ed766c97bb..c2d77db3a1 100644 --- a/e2e/start/basic-rsc/app/routes/posts.$postId.tsx +++ b/e2e/start/basic-rsc/app/routes/posts.$postId.tsx @@ -1,7 +1,8 @@ import { ErrorComponent, Link, createFileRoute } from '@tanstack/react-router' import { createServerFn } from '@tanstack/start' -import { fetchPost } from '../utils/posts' import type { ErrorComponentProps } from '@tanstack/react-router' + +import { fetchPost } from '~/utils/posts' import { NotFound } from '~/components/NotFound' const renderPost = createServerFn({ method: 'GET' }) @@ -29,7 +30,7 @@ const renderPost = createServerFn({ method: 'GET' }) export const Route = createFileRoute('/posts/$postId')({ loader: async ({ params: { postId } }) => renderPost({ data: postId }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostComponent, notFoundComponent: () => { return Post not found diff --git a/e2e/start/basic-rsc/app/routes/posts.index.tsx b/e2e/start/basic-rsc/app/routes/posts.index.tsx index 1b491e46be..5b5f08f95b 100644 --- a/e2e/start/basic-rsc/app/routes/posts.index.tsx +++ b/e2e/start/basic-rsc/app/routes/posts.index.tsx @@ -1,6 +1,5 @@ import { createFileRoute } from '@tanstack/react-router' -// @ts-ignore export const Route = createFileRoute('/posts/')({ component: PostsIndexComponent, }) diff --git a/e2e/start/basic-rsc/app/routes/posts.tsx b/e2e/start/basic-rsc/app/routes/posts.tsx index eda2c4f0cf..1e0be42f75 100644 --- a/e2e/start/basic-rsc/app/routes/posts.tsx +++ b/e2e/start/basic-rsc/app/routes/posts.tsx @@ -1,4 +1,3 @@ -// import * as React from 'react' import { createFileRoute } from '@tanstack/react-router' import { createServerFn, renderRsc } from '@tanstack/start' import { renderPosts } from '~/utils/renderPosts' diff --git a/e2e/start/basic-rsc/app/routes/posts_.$postId.deep.tsx b/e2e/start/basic-rsc/app/routes/posts_.$postId.deep.tsx index b095d42294..13d368cf9c 100644 --- a/e2e/start/basic-rsc/app/routes/posts_.$postId.deep.tsx +++ b/e2e/start/basic-rsc/app/routes/posts_.$postId.deep.tsx @@ -1,10 +1,10 @@ -import { createFileRoute, Link } from '@tanstack/react-router' -import { PostErrorComponent } from './posts.$postId' +import { Link, createFileRoute } from '@tanstack/react-router' import { fetchPost } from '../utils/posts' +import { PostErrorComponent } from './posts.$postId' export const Route = createFileRoute('/posts_/$postId/deep')({ loader: async ({ params: { postId } }) => fetchPost(postId), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostDeepComponent, }) diff --git a/e2e/start/basic-tsr-config/src/app/client.tsx b/e2e/start/basic-tsr-config/src/app/client.tsx index 8d07d8bac1..b14d8aac68 100644 --- a/e2e/start/basic-tsr-config/src/app/client.tsx +++ b/e2e/start/basic-tsr-config/src/app/client.tsx @@ -1,4 +1,3 @@ -// app/client.tsx /// import { hydrateRoot } from 'react-dom/client' import { StartClient } from '@tanstack/start' @@ -6,4 +5,4 @@ import { createRouter } from './router' const router = createRouter() -hydrateRoot(document!, ) +hydrateRoot(document, ) diff --git a/e2e/start/basic-tsr-config/src/app/router.tsx b/e2e/start/basic-tsr-config/src/app/router.tsx index dc640c5f4c..d0e2297dce 100644 --- a/e2e/start/basic-tsr-config/src/app/router.tsx +++ b/e2e/start/basic-tsr-config/src/app/router.tsx @@ -1,4 +1,3 @@ -// app/router.tsx import { createRouter as createTanStackRouter } from '@tanstack/react-router' import { routeTree } from './routeTree.gen' diff --git a/e2e/start/basic-tsr-config/src/app/routes/__root.tsx b/e2e/start/basic-tsr-config/src/app/routes/__root.tsx index 34ed08e02c..5a48b25d39 100644 --- a/e2e/start/basic-tsr-config/src/app/routes/__root.tsx +++ b/e2e/start/basic-tsr-config/src/app/routes/__root.tsx @@ -1,22 +1,26 @@ -// app/routes/__root.tsx -import { createRootRoute } from '@tanstack/react-router' -import { Outlet, ScrollRestoration } from '@tanstack/react-router' -import { Meta, Scripts } from '@tanstack/start' import * as React from 'react' +import { + Outlet, + ScrollRestoration, + createRootRoute, +} from '@tanstack/react-router' +import { Meta, Scripts } from '@tanstack/start' export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - { - title: 'TanStack Start Starter', - }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + { + title: 'TanStack Start Starter', + }, + ], + }), component: RootComponent, }) diff --git a/e2e/start/basic-tsr-config/src/app/routes/index.tsx b/e2e/start/basic-tsr-config/src/app/routes/index.tsx index b23814188f..47b3263237 100644 --- a/e2e/start/basic-tsr-config/src/app/routes/index.tsx +++ b/e2e/start/basic-tsr-config/src/app/routes/index.tsx @@ -1,4 +1,3 @@ -// app/routes/index.tsx import { createFileRoute, useRouter } from '@tanstack/react-router' import { createServerFn } from '@tanstack/start' diff --git a/e2e/start/basic-tsr-config/src/app/ssr.tsx b/e2e/start/basic-tsr-config/src/app/ssr.tsx index c74eeaedc7..f2d33f9030 100644 --- a/e2e/start/basic-tsr-config/src/app/ssr.tsx +++ b/e2e/start/basic-tsr-config/src/app/ssr.tsx @@ -1,4 +1,3 @@ -// app/ssr.tsx /// import { createStartHandler, diff --git a/e2e/start/basic/app/client.tsx b/e2e/start/basic/app/client.tsx index ffee5f382c..b14d8aac68 100644 --- a/e2e/start/basic/app/client.tsx +++ b/e2e/start/basic/app/client.tsx @@ -1,3 +1,4 @@ +/// import { hydrateRoot } from 'react-dom/client' import { StartClient } from '@tanstack/start' import { createRouter } from './router' diff --git a/e2e/start/basic/app/components/DefaultCatchBoundary.tsx b/e2e/start/basic/app/components/DefaultCatchBoundary.tsx index f0ce51dc57..15f316681c 100644 --- a/e2e/start/basic/app/components/DefaultCatchBoundary.tsx +++ b/e2e/start/basic/app/components/DefaultCatchBoundary.tsx @@ -1,11 +1,11 @@ import { ErrorComponent, - ErrorComponentProps, Link, rootRouteId, useMatch, useRouter, } from '@tanstack/react-router' +import type { ErrorComponentProps } from '@tanstack/react-router' export function DefaultCatchBoundary({ error }: ErrorComponentProps) { const router = useRouter() diff --git a/e2e/start/basic/app/routes/__root.tsx b/e2e/start/basic/app/routes/__root.tsx index 69aa1768b6..3c28fb6036 100644 --- a/e2e/start/basic/app/routes/__root.tsx +++ b/e2e/start/basic/app/routes/__root.tsx @@ -1,3 +1,4 @@ +import * as React from 'react' import { Link, Outlet, @@ -6,50 +7,51 @@ import { } from '@tanstack/react-router' import { TanStackRouterDevtools } from '@tanstack/router-devtools' import { Meta, Scripts } from '@tanstack/start' -import * as React from 'react' + import { DefaultCatchBoundary } from '~/components/DefaultCatchBoundary' import { NotFound } from '~/components/NotFound' -// @ts-expect-error import appCss from '~/styles/app.css?url' import { seo } from '~/utils/seo' export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), errorComponent: (props) => { return ( diff --git a/e2e/start/basic/app/routes/api.users.ts b/e2e/start/basic/app/routes/api.users.ts index 3b11af9b9d..3bcaf3446b 100644 --- a/e2e/start/basic/app/routes/api.users.ts +++ b/e2e/start/basic/app/routes/api.users.ts @@ -1,7 +1,8 @@ import { json } from '@tanstack/start' import { createAPIFileRoute } from '@tanstack/start/api' import axios from 'redaxios' -import type { User } from '../utils/users' + +import type { User } from '~/utils/users' export const Route = createAPIFileRoute('/api/users')({ GET: async ({ request }) => { diff --git a/e2e/start/basic/app/routes/api/users.$id.ts b/e2e/start/basic/app/routes/api/users.$id.ts index 849d45e8d0..044d1fd4c8 100644 --- a/e2e/start/basic/app/routes/api/users.$id.ts +++ b/e2e/start/basic/app/routes/api/users.$id.ts @@ -1,7 +1,8 @@ import { json } from '@tanstack/start' import { createAPIFileRoute } from '@tanstack/start/api' import axios from 'redaxios' -import type { User } from '../../utils/users' + +import type { User } from '~/utils/users' export const Route = createAPIFileRoute('/api/users/$id')({ GET: async ({ request, params }) => { diff --git a/e2e/start/basic/app/routes/posts.$postId.tsx b/e2e/start/basic/app/routes/posts.$postId.tsx index 8539e8c7db..005228a0fe 100644 --- a/e2e/start/basic/app/routes/posts.$postId.tsx +++ b/e2e/start/basic/app/routes/posts.$postId.tsx @@ -1,11 +1,12 @@ import { ErrorComponent, Link, createFileRoute } from '@tanstack/react-router' -import { fetchPost } from '../utils/posts' import type { ErrorComponentProps } from '@tanstack/react-router' + +import { fetchPost } from '~/utils/posts' import { NotFound } from '~/components/NotFound' export const Route = createFileRoute('/posts/$postId')({ loader: async ({ params: { postId } }) => fetchPost({ data: postId }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostComponent, notFoundComponent: () => { return Post not found diff --git a/e2e/start/basic/app/routes/posts.tsx b/e2e/start/basic/app/routes/posts.tsx index ae49032459..5a67375c84 100644 --- a/e2e/start/basic/app/routes/posts.tsx +++ b/e2e/start/basic/app/routes/posts.tsx @@ -1,5 +1,6 @@ import { Link, Outlet, createFileRoute } from '@tanstack/react-router' -import { fetchPosts } from '../utils/posts' + +import { fetchPosts } from '~/utils/posts' export const Route = createFileRoute('/posts')({ loader: async () => fetchPosts(), diff --git a/e2e/start/basic/app/routes/posts_.$postId.deep.tsx b/e2e/start/basic/app/routes/posts_.$postId.deep.tsx index a19a578db5..e8f733560b 100644 --- a/e2e/start/basic/app/routes/posts_.$postId.deep.tsx +++ b/e2e/start/basic/app/routes/posts_.$postId.deep.tsx @@ -1,10 +1,11 @@ import { Link, createFileRoute } from '@tanstack/react-router' -import { fetchPost } from '../utils/posts' + import { PostErrorComponent } from './posts.$postId' +import { fetchPost } from '~/utils/posts' export const Route = createFileRoute('/posts_/$postId/deep')({ loader: async ({ params: { postId } }) => fetchPost({ data: postId }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostDeepComponent, }) diff --git a/e2e/start/basic/app/routes/status.tsx b/e2e/start/basic/app/routes/status.tsx index fd761aaf35..b1bd160706 100644 --- a/e2e/start/basic/app/routes/status.tsx +++ b/e2e/start/basic/app/routes/status.tsx @@ -1,6 +1,5 @@ import { createFileRoute } from '@tanstack/react-router' import { createServerFn, useServerFn } from '@tanstack/start' - import { setResponseStatus } from 'vinxi/http' export const helloFn = createServerFn().handler(() => { diff --git a/e2e/start/basic/app/routes/users.$userId.tsx b/e2e/start/basic/app/routes/users.$userId.tsx index 573377c758..1e2921411a 100644 --- a/e2e/start/basic/app/routes/users.$userId.tsx +++ b/e2e/start/basic/app/routes/users.$userId.tsx @@ -1,7 +1,9 @@ import { ErrorComponent, createFileRoute } from '@tanstack/react-router' import axios from 'redaxios' import type { ErrorComponentProps } from '@tanstack/react-router' -import { DEPLOY_URL, type User } from '~/utils/users' + +import type { User } from '~/utils/users' +import { DEPLOY_URL } from '~/utils/users' import { NotFound } from '~/components/NotFound' export const Route = createFileRoute('/users/$userId')({ diff --git a/e2e/start/basic/app/routes/users.tsx b/e2e/start/basic/app/routes/users.tsx index 77a6fbe864..45e070657e 100644 --- a/e2e/start/basic/app/routes/users.tsx +++ b/e2e/start/basic/app/routes/users.tsx @@ -1,6 +1,8 @@ import { Link, Outlet, createFileRoute } from '@tanstack/react-router' import axios from 'redaxios' -import { DEPLOY_URL, type User } from '../utils/users' + +import type { User } from '~/utils/users' +import { DEPLOY_URL } from '~/utils/users' export const Route = createFileRoute('/users')({ loader: async () => { diff --git a/e2e/start/clerk-basic/app/client.tsx b/e2e/start/clerk-basic/app/client.tsx index b887037fc4..3bfe090a3e 100644 --- a/e2e/start/clerk-basic/app/client.tsx +++ b/e2e/start/clerk-basic/app/client.tsx @@ -1,3 +1,4 @@ +/// import { hydrateRoot } from 'react-dom/client' import { StartClient } from '@tanstack/start' import { createRouter } from './router' diff --git a/e2e/start/clerk-basic/app/routes/__root.tsx b/e2e/start/clerk-basic/app/routes/__root.tsx index db877d6e11..ffcca2b011 100644 --- a/e2e/start/clerk-basic/app/routes/__root.tsx +++ b/e2e/start/clerk-basic/app/routes/__root.tsx @@ -30,37 +30,39 @@ const fetchClerkAuth = createServerFn({ method: 'GET' }).handler(async () => { }) export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), beforeLoad: async () => { const { user } = await fetchClerkAuth() diff --git a/e2e/start/clerk-basic/app/routes/_authed/posts.$postId.tsx b/e2e/start/clerk-basic/app/routes/_authed/posts.$postId.tsx index e4680c6070..27296b9658 100644 --- a/e2e/start/clerk-basic/app/routes/_authed/posts.$postId.tsx +++ b/e2e/start/clerk-basic/app/routes/_authed/posts.$postId.tsx @@ -1,11 +1,12 @@ import { ErrorComponent, createFileRoute } from '@tanstack/react-router' import type { ErrorComponentProps } from '@tanstack/react-router' + import { NotFound } from '~/components/NotFound.js' import { fetchPost } from '~/utils/posts.js' export const Route = createFileRoute('/_authed/posts/$postId')({ loader: ({ params: { postId } }) => fetchPost({ data: postId }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostComponent, notFoundComponent: () => { return Post not found diff --git a/e2e/start/clerk-basic/app/routes/_authed/posts.tsx b/e2e/start/clerk-basic/app/routes/_authed/posts.tsx index 86c8ef4138..c01f12c49a 100644 --- a/e2e/start/clerk-basic/app/routes/_authed/posts.tsx +++ b/e2e/start/clerk-basic/app/routes/_authed/posts.tsx @@ -1,4 +1,5 @@ import { Link, Outlet, createFileRoute } from '@tanstack/react-router' + import { fetchPosts } from '~/utils/posts.js' export const Route = createFileRoute('/_authed/posts')({ diff --git a/e2e/start/clerk-basic/app/routes/_authed/profile.$.tsx b/e2e/start/clerk-basic/app/routes/_authed/profile.$.tsx index 208a38e230..1e5a8b1429 100644 --- a/e2e/start/clerk-basic/app/routes/_authed/profile.$.tsx +++ b/e2e/start/clerk-basic/app/routes/_authed/profile.$.tsx @@ -1,4 +1,5 @@ import { Link, Outlet, createFileRoute } from '@tanstack/react-router' + import { fetchPosts } from '~/utils/posts.js' export const Route = createFileRoute('/_authed/profile/$')({ diff --git a/e2e/start/website/app/routes/$project.$version.docs.framework.$framework.$.tsx b/e2e/start/website/app/routes/$project.$version.docs.framework.$framework.$.tsx index de3326d7d4..055f77622b 100644 --- a/e2e/start/website/app/routes/$project.$version.docs.framework.$framework.$.tsx +++ b/e2e/start/website/app/routes/$project.$version.docs.framework.$framework.$.tsx @@ -11,10 +11,11 @@ export const Route = createFileRoute( getDocument({ data: _splat!, }), - meta: ({ loaderData, params }) => - seo({ - title: `${loaderData.title} | TanStack ${capitalize(params.project)} ${capitalize(params.framework)}`, + head: ({ loaderData, params }) => ({ + meta: seo({ + title: `${loaderData?.title || 'Project'} | TanStack ${capitalize(params.project)} ${capitalize(params.framework)}`, }), + }), errorComponent: PostErrorComponent, component: Page, notFoundComponent: () => { diff --git a/e2e/start/website/app/routes/$project.$version.docs.framework.$framework.examples.$.tsx b/e2e/start/website/app/routes/$project.$version.docs.framework.$framework.examples.$.tsx index a06b4ec1b3..5d5cbe324d 100644 --- a/e2e/start/website/app/routes/$project.$version.docs.framework.$framework.examples.$.tsx +++ b/e2e/start/website/app/routes/$project.$version.docs.framework.$framework.examples.$.tsx @@ -5,10 +5,11 @@ import { capitalize, seo } from '~/utils/seo' export const Route = createFileRoute( '/$project/$version/docs/framework/$framework/examples/$', )({ - meta: ({ params }) => - seo({ + head: ({ params }) => ({ + meta: seo({ title: `${capitalize(params._splat || '')} Example | TanStack ${capitalize(params.project)} ${capitalize(params.framework)}`, }), + }), component: Page, notFoundComponent: () => { return Example not found diff --git a/e2e/start/website/app/routes/__root.tsx b/e2e/start/website/app/routes/__root.tsx index a7d9d48157..0a0ff80f24 100644 --- a/e2e/start/website/app/routes/__root.tsx +++ b/e2e/start/website/app/routes/__root.tsx @@ -12,41 +12,43 @@ import appCss from '~/styles/app.css?url' import { seo } from '~/utils/seo' export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: 'TanStack Website', - description: `TanStack projects are type-safe!!!`, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: 'TanStack Website', + description: `TanStack projects are type-safe!!!`, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), errorComponent: (props) => { return ( diff --git a/e2e/start/website/app/routes/_library.$project.tsx b/e2e/start/website/app/routes/_library.$project.tsx index 822158d3be..3384fcf3a0 100644 --- a/e2e/start/website/app/routes/_library.$project.tsx +++ b/e2e/start/website/app/routes/_library.$project.tsx @@ -4,7 +4,9 @@ import { seo } from '~/utils/seo' export const Route = createFileRoute('/_library/$project')({ loader: ({ params: { project } }) => getProject({ data: project }), - meta: ({ loaderData }) => seo({ title: `TanStack ${loaderData.name}` }), + head: ({ loaderData }) => ({ + meta: seo({ title: `TanStack ${loaderData?.name || 'Project'}` }), + }), component: () => (
diff --git a/examples/react/basic-file-based/src/routes/posts.$postId.tsx b/examples/react/basic-file-based/src/routes/posts.$postId.tsx index febb02ab2f..cded91ef96 100644 --- a/examples/react/basic-file-based/src/routes/posts.$postId.tsx +++ b/examples/react/basic-file-based/src/routes/posts.$postId.tsx @@ -5,7 +5,7 @@ import type { ErrorComponentProps } from '@tanstack/react-router' export const Route = createFileRoute('/posts/$postId')({ loader: async ({ params: { postId } }) => fetchPost(postId), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, notFoundComponent: () => { return

Post not found

}, diff --git a/examples/react/basic-react-query-file-based/src/routes/posts.$postId.tsx b/examples/react/basic-react-query-file-based/src/routes/posts.$postId.tsx index 78455fdcdf..4cf6beca88 100644 --- a/examples/react/basic-react-query-file-based/src/routes/posts.$postId.tsx +++ b/examples/react/basic-react-query-file-based/src/routes/posts.$postId.tsx @@ -20,7 +20,7 @@ export const Route = createFileRoute('/posts/$postId')({ component: PostComponent, }) -export function PostErrorComponent({ error, reset }: ErrorComponentProps) { +export function PostErrorComponent({ error }: ErrorComponentProps) { const router = useRouter() if (error instanceof PostNotFoundError) { return
{error.message}
diff --git a/examples/react/basic-react-query/src/main.tsx b/examples/react/basic-react-query/src/main.tsx index a5455491c0..0601c115e4 100644 --- a/examples/react/basic-react-query/src/main.tsx +++ b/examples/react/basic-react-query/src/main.tsx @@ -2,7 +2,6 @@ import React from 'react' import ReactDOM from 'react-dom/client' import { ErrorComponent, - type ErrorComponentProps, Link, Outlet, RouterProvider, @@ -20,6 +19,7 @@ import { useSuspenseQuery, } from '@tanstack/react-query' import { NotFoundError, postQueryOptions, postsQueryOptions } from './posts' +import type { ErrorComponentProps } from '@tanstack/react-router' const rootRoute = createRootRouteWithContext<{ queryClient: QueryClient @@ -122,7 +122,7 @@ const postRoute = createRoute({ component: PostRouteComponent, }) -function PostErrorComponent({ error, reset }: ErrorComponentProps) { +function PostErrorComponent({ error }: ErrorComponentProps) { const router = useRouter() if (error instanceof NotFoundError) { return
{error.message}
diff --git a/examples/react/basic-ssr-file-based/src/routes/__root.tsx b/examples/react/basic-ssr-file-based/src/routes/__root.tsx index 9424dc2259..97a87f8085 100644 --- a/examples/react/basic-ssr-file-based/src/routes/__root.tsx +++ b/examples/react/basic-ssr-file-based/src/routes/__root.tsx @@ -8,39 +8,41 @@ import { Meta, Scripts } from '@tanstack/start' import type { RouterContext } from '../routerContext' export const Route = createRootRouteWithContext()({ - meta: () => [ - { - title: 'TanStack Router SSR Basic File Based', - }, - { - charSet: 'UTF-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1.0', - }, - ], - scripts: () => [ - { - src: 'https://cdn.tailwindcss.com', - }, - { - type: 'module', - children: `import RefreshRuntime from "/@react-refresh" -RefreshRuntime.injectIntoGlobalHook(window) -window.$RefreshReg$ = () => {} -window.$RefreshSig$ = () => (type) => type -window.__vite_plugin_react_preamble_installed__ = true`, - }, - { - type: 'module', - src: '/@vite/client', - }, - { - type: 'module', - src: '/src/entry-client.tsx', - }, - ], + head: () => ({ + meta: [ + { + title: 'TanStack Router SSR Basic File Based', + }, + { + charSet: 'UTF-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1.0', + }, + ], + scripts: [ + { + src: 'https://cdn.tailwindcss.com', + }, + { + type: 'module', + children: `import RefreshRuntime from "/@react-refresh" + RefreshRuntime.injectIntoGlobalHook(window) + window.$RefreshReg$ = () => {} + window.$RefreshSig$ = () => (type) => type + window.__vite_plugin_react_preamble_installed__ = true`, + }, + { + type: 'module', + src: '/@vite/client', + }, + { + type: 'module', + src: '/src/entry-client.tsx', + }, + ], + }), component: RootComponent, }) diff --git a/examples/react/basic-ssr-file-based/src/routes/error.tsx b/examples/react/basic-ssr-file-based/src/routes/error.tsx index 2b3599380f..52d42f2a99 100644 --- a/examples/react/basic-ssr-file-based/src/routes/error.tsx +++ b/examples/react/basic-ssr-file-based/src/routes/error.tsx @@ -10,7 +10,7 @@ export const Route = createFileRoute('/error')({ errorComponent: ({ error }) => { return (
-

Caught: {(error as Error).message}

+

Caught: {error.message}

(This page has a 50% chance of throwing an error)

) diff --git a/examples/react/basic-ssr-file-based/src/routes/posts.tsx b/examples/react/basic-ssr-file-based/src/routes/posts.tsx index 33da97b194..3699478d0a 100644 --- a/examples/react/basic-ssr-file-based/src/routes/posts.tsx +++ b/examples/react/basic-ssr-file-based/src/routes/posts.tsx @@ -1,5 +1,5 @@ import * as React from 'react' -import { createFileRoute, Link, Outlet } from '@tanstack/react-router' +import { Link, Outlet, createFileRoute } from '@tanstack/react-router' export type PostType = { id: string @@ -14,7 +14,7 @@ export const Route = createFileRoute('/posts')({ setTimeout(r, 300 + Math.round(Math.random() * 300)), ) return fetch('https://jsonplaceholder.typicode.com/posts') - .then((d) => d.json() as Promise) + .then((d) => d.json() as Promise>) .then((d) => d.slice(0, 10)) }, component: PostsComponent, @@ -26,7 +26,7 @@ function PostsComponent() { return (
    - {posts?.map((post) => { + {posts.map((post) => { return (
  • { diff --git a/examples/react/basic-ssr-streaming-file-based/src/routes/__root.tsx b/examples/react/basic-ssr-streaming-file-based/src/routes/__root.tsx index 272dd22eb5..e9eff8ee7a 100644 --- a/examples/react/basic-ssr-streaming-file-based/src/routes/__root.tsx +++ b/examples/react/basic-ssr-streaming-file-based/src/routes/__root.tsx @@ -9,39 +9,41 @@ import { Meta, Scripts } from '@tanstack/start' import type { RouterContext } from '../routerContext' export const Route = createRootRouteWithContext()({ - meta: () => [ - { - title: 'TanStack Router SSR Basic File Based', - }, - { - charSet: 'UTF-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1.0', - }, - ], - scripts: () => [ - { - src: 'https://cdn.tailwindcss.com', - }, - { - type: 'module', - children: `import RefreshRuntime from "/@react-refresh" -RefreshRuntime.injectIntoGlobalHook(window) -window.$RefreshReg$ = () => {} -window.$RefreshSig$ = () => (type) => type -window.__vite_plugin_react_preamble_installed__ = true`, - }, - { - type: 'module', - src: '/@vite/client', - }, - { - type: 'module', - src: '/src/entry-client.tsx', - }, - ], + head: () => ({ + meta: [ + { + title: 'TanStack Router SSR Basic File Based', + }, + { + charSet: 'UTF-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1.0', + }, + ], + scripts: [ + { + src: 'https://cdn.tailwindcss.com', + }, + { + type: 'module', + children: `import RefreshRuntime from "/@react-refresh" + RefreshRuntime.injectIntoGlobalHook(window) + window.$RefreshReg$ = () => {} + window.$RefreshSig$ = () => (type) => type + window.__vite_plugin_react_preamble_installed__ = true`, + }, + { + type: 'module', + src: '/@vite/client', + }, + { + type: 'module', + src: '/src/entry-client.tsx', + }, + ], + }), component: RootComponent, }) diff --git a/examples/react/basic-ssr-streaming-file-based/src/routes/posts.tsx b/examples/react/basic-ssr-streaming-file-based/src/routes/posts.tsx index 5dad9b0623..ad2b0082ad 100644 --- a/examples/react/basic-ssr-streaming-file-based/src/routes/posts.tsx +++ b/examples/react/basic-ssr-streaming-file-based/src/routes/posts.tsx @@ -1,5 +1,5 @@ import * as React from 'react' -import { createFileRoute, Link, Outlet } from '@tanstack/react-router' +import { Link, Outlet, createFileRoute } from '@tanstack/react-router' export type PostType = { id: string @@ -14,7 +14,7 @@ export const Route = createFileRoute('/posts')({ setTimeout(r, 300 + Math.round(Math.random() * 300)), ) return fetch('https://jsonplaceholder.typicode.com/posts') - .then((d) => d.json() as Promise) + .then((d) => d.json() as Promise>) .then((d) => d.slice(0, 10)) }, component: PostsComponent, @@ -26,7 +26,7 @@ function PostsComponent() { return (
      - {posts?.map((post) => { + {posts.map((post) => { return (
    • This is the index
      , diff --git a/examples/react/basic-virtual-inside-file-based/src/routes/posts/details.tsx b/examples/react/basic-virtual-inside-file-based/src/routes/posts/details.tsx index 948d52d6d6..6479bdf803 100644 --- a/examples/react/basic-virtual-inside-file-based/src/routes/posts/details.tsx +++ b/examples/react/basic-virtual-inside-file-based/src/routes/posts/details.tsx @@ -5,7 +5,7 @@ import type { ErrorComponentProps } from '@tanstack/react-router' export const Route = createFileRoute('/posts/$postId')({ loader: async ({ params: { postId } }) => fetchPost(postId), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, notFoundComponent: () => { return

      Post not found

      }, diff --git a/examples/react/basic/src/main.tsx b/examples/react/basic/src/main.tsx index f75bdb8629..873374a010 100644 --- a/examples/react/basic/src/main.tsx +++ b/examples/react/basic/src/main.tsx @@ -1,7 +1,6 @@ import ReactDOM from 'react-dom/client' import { ErrorComponent, - type ErrorComponentProps, Link, Outlet, RouterProvider, @@ -11,6 +10,7 @@ import { } from '@tanstack/react-router' import { TanStackRouterDevtools } from '@tanstack/router-devtools' import { NotFoundError, fetchPost, fetchPosts } from './posts' +import type { ErrorComponentProps } from '@tanstack/react-router' const rootRoute = createRootRoute({ component: RootComponent, diff --git a/examples/react/kitchen-sink-file-based/src/routes/_auth.tsx b/examples/react/kitchen-sink-file-based/src/routes/_auth.tsx index 30fdcf9f28..f4f3876f26 100644 --- a/examples/react/kitchen-sink-file-based/src/routes/_auth.tsx +++ b/examples/react/kitchen-sink-file-based/src/routes/_auth.tsx @@ -1,4 +1,3 @@ -import * as React from 'react' import { createFileRoute, redirect } from '@tanstack/react-router' import { auth } from '../utils/auth' diff --git a/examples/react/router-monorepo-react-query/packages/app/src/main.tsx b/examples/react/router-monorepo-react-query/packages/app/src/main.tsx index ffb2c00f4f..dc22c54020 100644 --- a/examples/react/router-monorepo-react-query/packages/app/src/main.tsx +++ b/examples/react/router-monorepo-react-query/packages/app/src/main.tsx @@ -2,7 +2,7 @@ import React, { StrictMode } from 'react' import ReactDOM from 'react-dom/client' import { RouterProvider } from '@tanstack/react-router' import { QueryClientProvider } from '@tanstack/react-query' -import { Outlet, queryClient, router } from '@router-mono-react-query/router' +import { queryClient, router } from '@router-mono-react-query/router' import { PostErrorComponent, PostIdComponent, diff --git a/examples/react/router-monorepo-simple/packages/app/src/main.tsx b/examples/react/router-monorepo-simple/packages/app/src/main.tsx index 74283c5c8b..e4bac0e6d9 100644 --- a/examples/react/router-monorepo-simple/packages/app/src/main.tsx +++ b/examples/react/router-monorepo-simple/packages/app/src/main.tsx @@ -26,6 +26,7 @@ function EmptyComponent() { Object.entries(routerMap).forEach(([path, component]) => { const foundRoute = router.routesById[path as RouterIds] foundRoute.update({ + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition component: component ?? EmptyComponent, }) }) diff --git a/examples/react/start-basic-auth/app/components/DefaultCatchBoundary.tsx b/examples/react/start-basic-auth/app/components/DefaultCatchBoundary.tsx index f0ce51dc57..15f316681c 100644 --- a/examples/react/start-basic-auth/app/components/DefaultCatchBoundary.tsx +++ b/examples/react/start-basic-auth/app/components/DefaultCatchBoundary.tsx @@ -1,11 +1,11 @@ import { ErrorComponent, - ErrorComponentProps, Link, rootRouteId, useMatch, useRouter, } from '@tanstack/react-router' +import type { ErrorComponentProps } from '@tanstack/react-router' export function DefaultCatchBoundary({ error }: ErrorComponentProps) { const router = useRouter() diff --git a/examples/react/start-basic-auth/app/routes/__root.tsx b/examples/react/start-basic-auth/app/routes/__root.tsx index 3ab9c663b8..1b09411989 100644 --- a/examples/react/start-basic-auth/app/routes/__root.tsx +++ b/examples/react/start-basic-auth/app/routes/__root.tsx @@ -27,42 +27,44 @@ const fetchUser = createServerFn({ method: 'GET' }).handler(async () => { }) export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), beforeLoad: async () => { const user = await fetchUser() diff --git a/examples/react/start-basic-auth/app/routes/_authed/posts.$postId.tsx b/examples/react/start-basic-auth/app/routes/_authed/posts.$postId.tsx index e4680c6070..039271bb89 100644 --- a/examples/react/start-basic-auth/app/routes/_authed/posts.$postId.tsx +++ b/examples/react/start-basic-auth/app/routes/_authed/posts.$postId.tsx @@ -5,7 +5,7 @@ import { fetchPost } from '~/utils/posts.js' export const Route = createFileRoute('/_authed/posts/$postId')({ loader: ({ params: { postId } }) => fetchPost({ data: postId }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostComponent, notFoundComponent: () => { return Post not found diff --git a/examples/react/start-basic-react-query/app/components/DefaultCatchBoundary.tsx b/examples/react/start-basic-react-query/app/components/DefaultCatchBoundary.tsx index f0ce51dc57..15f316681c 100644 --- a/examples/react/start-basic-react-query/app/components/DefaultCatchBoundary.tsx +++ b/examples/react/start-basic-react-query/app/components/DefaultCatchBoundary.tsx @@ -1,11 +1,11 @@ import { ErrorComponent, - ErrorComponentProps, Link, rootRouteId, useMatch, useRouter, } from '@tanstack/react-router' +import type { ErrorComponentProps } from '@tanstack/react-router' export function DefaultCatchBoundary({ error }: ErrorComponentProps) { const router = useRouter() diff --git a/examples/react/start-basic-react-query/app/routes/__root.tsx b/examples/react/start-basic-react-query/app/routes/__root.tsx index 849d02e1ba..c916cbeda5 100644 --- a/examples/react/start-basic-react-query/app/routes/__root.tsx +++ b/examples/react/start-basic-react-query/app/routes/__root.tsx @@ -17,42 +17,44 @@ import { seo } from '~/utils/seo' export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), errorComponent: (props) => { return ( diff --git a/examples/react/start-basic-react-query/app/routes/posts.$postId.tsx b/examples/react/start-basic-react-query/app/routes/posts.$postId.tsx index 546e3d2795..542a12a9f6 100644 --- a/examples/react/start-basic-react-query/app/routes/posts.$postId.tsx +++ b/examples/react/start-basic-react-query/app/routes/posts.$postId.tsx @@ -14,12 +14,10 @@ export const Route = createFileRoute('/posts/$postId')({ title: data.title, } }, - meta: ({ loaderData }) => [ - { - title: loaderData.title, - }, - ], - errorComponent: PostErrorComponent as any, + head: ({ loaderData }) => ({ + meta: loaderData ? [{ title: loaderData.title }] : undefined, + }), + errorComponent: PostErrorComponent, notFoundComponent: () => { return Post not found }, diff --git a/examples/react/start-basic-react-query/app/routes/posts.tsx b/examples/react/start-basic-react-query/app/routes/posts.tsx index 64600d15c4..b545663be2 100644 --- a/examples/react/start-basic-react-query/app/routes/posts.tsx +++ b/examples/react/start-basic-react-query/app/routes/posts.tsx @@ -6,7 +6,9 @@ export const Route = createFileRoute('/posts')({ loader: async ({ context }) => { await context.queryClient.ensureQueryData(postsQueryOptions()) }, - meta: () => [{ title: 'Posts' }], + head: () => ({ + meta: [{ title: 'Posts' }], + }), component: PostsComponent, }) diff --git a/examples/react/start-basic-react-query/app/routes/posts_.$postId.deep.tsx b/examples/react/start-basic-react-query/app/routes/posts_.$postId.deep.tsx index 219ba4771b..33f6475a55 100644 --- a/examples/react/start-basic-react-query/app/routes/posts_.$postId.deep.tsx +++ b/examples/react/start-basic-react-query/app/routes/posts_.$postId.deep.tsx @@ -13,12 +13,10 @@ export const Route = createFileRoute('/posts_/$postId/deep')({ title: data.title, } }, - meta: ({ loaderData }) => [ - { - title: loaderData.title, - }, - ], - errorComponent: PostErrorComponent as any, + head: ({ loaderData }) => ({ + meta: loaderData ? [{ title: loaderData.title }] : undefined, + }), + errorComponent: PostErrorComponent, component: PostDeepComponent, }) diff --git a/examples/react/start-basic-rsc/app/components/DefaultCatchBoundary.tsx b/examples/react/start-basic-rsc/app/components/DefaultCatchBoundary.tsx index f0ce51dc57..15f316681c 100644 --- a/examples/react/start-basic-rsc/app/components/DefaultCatchBoundary.tsx +++ b/examples/react/start-basic-rsc/app/components/DefaultCatchBoundary.tsx @@ -1,11 +1,11 @@ import { ErrorComponent, - ErrorComponentProps, Link, rootRouteId, useMatch, useRouter, } from '@tanstack/react-router' +import type { ErrorComponentProps } from '@tanstack/react-router' export function DefaultCatchBoundary({ error }: ErrorComponentProps) { const router = useRouter() diff --git a/examples/react/start-basic-rsc/app/routes/__root.tsx b/examples/react/start-basic-rsc/app/routes/__root.tsx index a938538aea..2e19225490 100644 --- a/examples/react/start-basic-rsc/app/routes/__root.tsx +++ b/examples/react/start-basic-rsc/app/routes/__root.tsx @@ -13,42 +13,44 @@ import appCss from '~/styles/app.css?url' import { seo } from '~/utils/seo' export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), errorComponent: (props) => { return ( diff --git a/examples/react/start-basic-rsc/app/routes/posts.$postId.tsx b/examples/react/start-basic-rsc/app/routes/posts.$postId.tsx index c682378671..b857d05e06 100644 --- a/examples/react/start-basic-rsc/app/routes/posts.$postId.tsx +++ b/examples/react/start-basic-rsc/app/routes/posts.$postId.tsx @@ -29,7 +29,7 @@ const renderPost = createServerFn({ method: 'GET' }) export const Route = createFileRoute('/posts/$postId')({ loader: async ({ params: { postId } }) => renderPost({ data: postId }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostComponent, notFoundComponent: () => { return Post not found diff --git a/examples/react/start-basic-rsc/app/routes/posts.index.tsx b/examples/react/start-basic-rsc/app/routes/posts.index.tsx index 1b491e46be..5b5f08f95b 100644 --- a/examples/react/start-basic-rsc/app/routes/posts.index.tsx +++ b/examples/react/start-basic-rsc/app/routes/posts.index.tsx @@ -1,6 +1,5 @@ import { createFileRoute } from '@tanstack/react-router' -// @ts-ignore export const Route = createFileRoute('/posts/')({ component: PostsIndexComponent, }) diff --git a/examples/react/start-basic-rsc/app/routes/posts.tsx b/examples/react/start-basic-rsc/app/routes/posts.tsx index eda2c4f0cf..1e0be42f75 100644 --- a/examples/react/start-basic-rsc/app/routes/posts.tsx +++ b/examples/react/start-basic-rsc/app/routes/posts.tsx @@ -1,4 +1,3 @@ -// import * as React from 'react' import { createFileRoute } from '@tanstack/react-router' import { createServerFn, renderRsc } from '@tanstack/start' import { renderPosts } from '~/utils/renderPosts' diff --git a/examples/react/start-basic-rsc/app/routes/posts_.$postId.deep.tsx b/examples/react/start-basic-rsc/app/routes/posts_.$postId.deep.tsx index b095d42294..13d368cf9c 100644 --- a/examples/react/start-basic-rsc/app/routes/posts_.$postId.deep.tsx +++ b/examples/react/start-basic-rsc/app/routes/posts_.$postId.deep.tsx @@ -1,10 +1,10 @@ -import { createFileRoute, Link } from '@tanstack/react-router' -import { PostErrorComponent } from './posts.$postId' +import { Link, createFileRoute } from '@tanstack/react-router' import { fetchPost } from '../utils/posts' +import { PostErrorComponent } from './posts.$postId' export const Route = createFileRoute('/posts_/$postId/deep')({ loader: async ({ params: { postId } }) => fetchPost(postId), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostDeepComponent, }) diff --git a/examples/react/start-basic/app/routeTree.gen.ts b/examples/react/start-basic/app/routeTree.gen.ts index 22021a2af7..9f7ab8107b 100644 --- a/examples/react/start-basic/app/routeTree.gen.ts +++ b/examples/react/start-basic/app/routeTree.gen.ts @@ -21,10 +21,10 @@ import { Route as UsersIndexImport } from './routes/users.index' import { Route as PostsIndexImport } from './routes/posts.index' import { Route as UsersUserIdImport } from './routes/users.$userId' import { Route as PostsPostIdImport } from './routes/posts.$postId' -import { Route as LayoutTestLayoutTest2Import } from './routes/_layoutTest/_layoutTest-2' +import { Route as LayoutLayout2Import } from './routes/_layout/_layout-2' import { Route as PostsPostIdDeepImport } from './routes/posts_.$postId.deep' -import { Route as LayoutTestLayoutTest2LayoutTestBImport } from './routes/_layoutTest/_layoutTest-2/layoutTest-b' -import { Route as LayoutTestLayoutTest2LayoutTestAImport } from './routes/_layoutTest/_layoutTest-2/layoutTest-a' +import { Route as LayoutLayout2LayoutBImport } from './routes/_layout/_layout-2/layout-b' +import { Route as LayoutLayout2LayoutAImport } from './routes/_layout/_layout-2/layout-a' // Create/Update Routes @@ -87,9 +87,9 @@ const PostsPostIdRoute = PostsPostIdImport.update({ getParentRoute: () => PostsRoute, } as any) -const LayoutTestLayoutTest2Route = LayoutTestLayoutTest2Import.update({ - id: '/_layoutTest/_layoutTest-2', - getParentRoute: () => rootRoute, +const LayoutLayout2Route = LayoutLayout2Import.update({ + id: '/_layout-2', + getParentRoute: () => LayoutRoute, } as any) const PostsPostIdDeepRoute = PostsPostIdDeepImport.update({ @@ -98,19 +98,17 @@ const PostsPostIdDeepRoute = PostsPostIdDeepImport.update({ getParentRoute: () => rootRoute, } as any) -const LayoutTestLayoutTest2LayoutTestBRoute = - LayoutTestLayoutTest2LayoutTestBImport.update({ - id: '/layoutTest-b', - path: '/layoutTest-b', - getParentRoute: () => LayoutTestLayoutTest2Route, - } as any) +const LayoutLayout2LayoutBRoute = LayoutLayout2LayoutBImport.update({ + id: '/layout-b', + path: '/layout-b', + getParentRoute: () => LayoutLayout2Route, +} as any) -const LayoutTestLayoutTest2LayoutTestARoute = - LayoutTestLayoutTest2LayoutTestAImport.update({ - id: '/layoutTest-a', - path: '/layoutTest-a', - getParentRoute: () => LayoutTestLayoutTest2Route, - } as any) +const LayoutLayout2LayoutARoute = LayoutLayout2LayoutAImport.update({ + id: '/layout-a', + path: '/layout-a', + getParentRoute: () => LayoutLayout2Route, +} as any) // Populate the FileRoutesByPath interface @@ -158,12 +156,12 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof UsersImport parentRoute: typeof rootRoute } - '/_layoutTest/_layoutTest-2': { - id: '/_layoutTest/_layoutTest-2' + '/_layout/_layout-2': { + id: '/_layout/_layout-2' path: '' fullPath: '' - preLoaderRoute: typeof LayoutTestLayoutTest2Import - parentRoute: typeof rootRoute + preLoaderRoute: typeof LayoutLayout2Import + parentRoute: typeof LayoutImport } '/posts/$postId': { id: '/posts/$postId' @@ -193,19 +191,19 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof UsersIndexImport parentRoute: typeof UsersImport } - '/_layoutTest/_layoutTest-2/layoutTest-a': { - id: '/_layoutTest/_layoutTest-2/layoutTest-a' - path: '/layoutTest-a' - fullPath: '/layoutTest-a' - preLoaderRoute: typeof LayoutTestLayoutTest2LayoutTestAImport - parentRoute: typeof LayoutTestLayoutTest2Import + '/_layout/_layout-2/layout-a': { + id: '/_layout/_layout-2/layout-a' + path: '/layout-a' + fullPath: '/layout-a' + preLoaderRoute: typeof LayoutLayout2LayoutAImport + parentRoute: typeof LayoutLayout2Import } - '/_layoutTest/_layoutTest-2/layoutTest-b': { - id: '/_layoutTest/_layoutTest-2/layoutTest-b' - path: '/layoutTest-b' - fullPath: '/layoutTest-b' - preLoaderRoute: typeof LayoutTestLayoutTest2LayoutTestBImport - parentRoute: typeof LayoutTestLayoutTest2Import + '/_layout/_layout-2/layout-b': { + id: '/_layout/_layout-2/layout-b' + path: '/layout-b' + fullPath: '/layout-b' + preLoaderRoute: typeof LayoutLayout2LayoutBImport + parentRoute: typeof LayoutLayout2Import } '/posts_/$postId/deep': { id: '/posts_/$postId/deep' @@ -219,6 +217,31 @@ declare module '@tanstack/react-router' { // Create and export the route tree +interface LayoutLayout2RouteChildren { + LayoutLayout2LayoutARoute: typeof LayoutLayout2LayoutARoute + LayoutLayout2LayoutBRoute: typeof LayoutLayout2LayoutBRoute +} + +const LayoutLayout2RouteChildren: LayoutLayout2RouteChildren = { + LayoutLayout2LayoutARoute: LayoutLayout2LayoutARoute, + LayoutLayout2LayoutBRoute: LayoutLayout2LayoutBRoute, +} + +const LayoutLayout2RouteWithChildren = LayoutLayout2Route._addFileChildren( + LayoutLayout2RouteChildren, +) + +interface LayoutRouteChildren { + LayoutLayout2Route: typeof LayoutLayout2RouteWithChildren +} + +const LayoutRouteChildren: LayoutRouteChildren = { + LayoutLayout2Route: LayoutLayout2RouteWithChildren, +} + +const LayoutRouteWithChildren = + LayoutRoute._addFileChildren(LayoutRouteChildren) + interface PostsRouteChildren { PostsPostIdRoute: typeof PostsPostIdRoute PostsIndexRoute: typeof PostsIndexRoute @@ -243,24 +266,9 @@ const UsersRouteChildren: UsersRouteChildren = { const UsersRouteWithChildren = UsersRoute._addFileChildren(UsersRouteChildren) -interface LayoutTestLayoutTest2RouteChildren { - LayoutTestLayoutTest2LayoutTestARoute: typeof LayoutTestLayoutTest2LayoutTestARoute - LayoutTestLayoutTest2LayoutTestBRoute: typeof LayoutTestLayoutTest2LayoutTestBRoute -} - -const LayoutTestLayoutTest2RouteChildren: LayoutTestLayoutTest2RouteChildren = { - LayoutTestLayoutTest2LayoutTestARoute: LayoutTestLayoutTest2LayoutTestARoute, - LayoutTestLayoutTest2LayoutTestBRoute: LayoutTestLayoutTest2LayoutTestBRoute, -} - -const LayoutTestLayoutTest2RouteWithChildren = - LayoutTestLayoutTest2Route._addFileChildren( - LayoutTestLayoutTest2RouteChildren, - ) - export interface FileRoutesByFullPath { '/': typeof IndexRoute - '': typeof LayoutTestLayoutTest2RouteWithChildren + '': typeof LayoutLayout2RouteWithChildren '/deferred': typeof DeferredRoute '/posts': typeof PostsRouteWithChildren '/redirect': typeof RedirectRoute @@ -269,40 +277,40 @@ export interface FileRoutesByFullPath { '/users/$userId': typeof UsersUserIdRoute '/posts/': typeof PostsIndexRoute '/users/': typeof UsersIndexRoute - '/layoutTest-a': typeof LayoutTestLayoutTest2LayoutTestARoute - '/layoutTest-b': typeof LayoutTestLayoutTest2LayoutTestBRoute + '/layout-a': typeof LayoutLayout2LayoutARoute + '/layout-b': typeof LayoutLayout2LayoutBRoute '/posts/$postId/deep': typeof PostsPostIdDeepRoute } export interface FileRoutesByTo { '/': typeof IndexRoute - '': typeof LayoutTestLayoutTest2RouteWithChildren + '': typeof LayoutLayout2RouteWithChildren '/deferred': typeof DeferredRoute '/redirect': typeof RedirectRoute '/posts/$postId': typeof PostsPostIdRoute '/users/$userId': typeof UsersUserIdRoute '/posts': typeof PostsIndexRoute '/users': typeof UsersIndexRoute - '/layoutTest-a': typeof LayoutTestLayoutTest2LayoutTestARoute - '/layoutTest-b': typeof LayoutTestLayoutTest2LayoutTestBRoute + '/layout-a': typeof LayoutLayout2LayoutARoute + '/layout-b': typeof LayoutLayout2LayoutBRoute '/posts/$postId/deep': typeof PostsPostIdDeepRoute } export interface FileRoutesById { __root__: typeof rootRoute '/': typeof IndexRoute - '/_layout': typeof LayoutRoute + '/_layout': typeof LayoutRouteWithChildren '/deferred': typeof DeferredRoute '/posts': typeof PostsRouteWithChildren '/redirect': typeof RedirectRoute '/users': typeof UsersRouteWithChildren - '/_layoutTest/_layoutTest-2': typeof LayoutTestLayoutTest2RouteWithChildren + '/_layout/_layout-2': typeof LayoutLayout2RouteWithChildren '/posts/$postId': typeof PostsPostIdRoute '/users/$userId': typeof UsersUserIdRoute '/posts/': typeof PostsIndexRoute '/users/': typeof UsersIndexRoute - '/_layoutTest/_layoutTest-2/layoutTest-a': typeof LayoutTestLayoutTest2LayoutTestARoute - '/_layoutTest/_layoutTest-2/layoutTest-b': typeof LayoutTestLayoutTest2LayoutTestBRoute + '/_layout/_layout-2/layout-a': typeof LayoutLayout2LayoutARoute + '/_layout/_layout-2/layout-b': typeof LayoutLayout2LayoutBRoute '/posts_/$postId/deep': typeof PostsPostIdDeepRoute } @@ -319,8 +327,8 @@ export interface FileRouteTypes { | '/users/$userId' | '/posts/' | '/users/' - | '/layoutTest-a' - | '/layoutTest-b' + | '/layout-a' + | '/layout-b' | '/posts/$postId/deep' fileRoutesByTo: FileRoutesByTo to: @@ -332,8 +340,8 @@ export interface FileRouteTypes { | '/users/$userId' | '/posts' | '/users' - | '/layoutTest-a' - | '/layoutTest-b' + | '/layout-a' + | '/layout-b' | '/posts/$postId/deep' id: | '__root__' @@ -343,36 +351,34 @@ export interface FileRouteTypes { | '/posts' | '/redirect' | '/users' - | '/_layoutTest/_layoutTest-2' + | '/_layout/_layout-2' | '/posts/$postId' | '/users/$userId' | '/posts/' | '/users/' - | '/_layoutTest/_layoutTest-2/layoutTest-a' - | '/_layoutTest/_layoutTest-2/layoutTest-b' + | '/_layout/_layout-2/layout-a' + | '/_layout/_layout-2/layout-b' | '/posts_/$postId/deep' fileRoutesById: FileRoutesById } export interface RootRouteChildren { IndexRoute: typeof IndexRoute - LayoutRoute: typeof LayoutRoute + LayoutRoute: typeof LayoutRouteWithChildren DeferredRoute: typeof DeferredRoute PostsRoute: typeof PostsRouteWithChildren RedirectRoute: typeof RedirectRoute UsersRoute: typeof UsersRouteWithChildren - LayoutTestLayoutTest2Route: typeof LayoutTestLayoutTest2RouteWithChildren PostsPostIdDeepRoute: typeof PostsPostIdDeepRoute } const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, - LayoutRoute: LayoutRoute, + LayoutRoute: LayoutRouteWithChildren, DeferredRoute: DeferredRoute, PostsRoute: PostsRouteWithChildren, RedirectRoute: RedirectRoute, UsersRoute: UsersRouteWithChildren, - LayoutTestLayoutTest2Route: LayoutTestLayoutTest2RouteWithChildren, PostsPostIdDeepRoute: PostsPostIdDeepRoute, } @@ -392,7 +398,6 @@ export const routeTree = rootRoute "/posts", "/redirect", "/users", - "/_layoutTest/_layoutTest-2", "/posts_/$postId/deep" ] }, @@ -400,7 +405,10 @@ export const routeTree = rootRoute "filePath": "index.tsx" }, "/_layout": { - "filePath": "_layout.tsx" + "filePath": "_layout.tsx", + "children": [ + "/_layout/_layout-2" + ] }, "/deferred": { "filePath": "deferred.tsx" @@ -422,11 +430,12 @@ export const routeTree = rootRoute "/users/" ] }, - "/_layoutTest/_layoutTest-2": { - "filePath": "_layoutTest/_layoutTest-2.tsx", + "/_layout/_layout-2": { + "filePath": "_layout/_layout-2.tsx", + "parent": "/_layout", "children": [ - "/_layoutTest/_layoutTest-2/layoutTest-a", - "/_layoutTest/_layoutTest-2/layoutTest-b" + "/_layout/_layout-2/layout-a", + "/_layout/_layout-2/layout-b" ] }, "/posts/$postId": { @@ -445,13 +454,13 @@ export const routeTree = rootRoute "filePath": "users.index.tsx", "parent": "/users" }, - "/_layoutTest/_layoutTest-2/layoutTest-a": { - "filePath": "_layoutTest/_layoutTest-2/layoutTest-a.tsx", - "parent": "/_layoutTest/_layoutTest-2" + "/_layout/_layout-2/layout-a": { + "filePath": "_layout/_layout-2/layout-a.tsx", + "parent": "/_layout/_layout-2" }, - "/_layoutTest/_layoutTest-2/layoutTest-b": { - "filePath": "_layoutTest/_layoutTest-2/layoutTest-b.tsx", - "parent": "/_layoutTest/_layoutTest-2" + "/_layout/_layout-2/layout-b": { + "filePath": "_layout/_layout-2/layout-b.tsx", + "parent": "/_layout/_layout-2" }, "/posts_/$postId/deep": { "filePath": "posts_.$postId.deep.tsx" diff --git a/examples/react/start-basic/app/routes/__root.tsx b/examples/react/start-basic/app/routes/__root.tsx index eb004a7c08..a2376f8364 100644 --- a/examples/react/start-basic/app/routes/__root.tsx +++ b/examples/react/start-basic/app/routes/__root.tsx @@ -13,42 +13,44 @@ import appCss from '~/styles/app.css?url' import { seo } from '~/utils/seo' export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), errorComponent: (props) => { return ( diff --git a/examples/react/start-basic/app/routes/_layoutTest/_layoutTest-2.tsx b/examples/react/start-basic/app/routes/_layout/_layout-2.tsx similarity index 90% rename from examples/react/start-basic/app/routes/_layoutTest/_layoutTest-2.tsx rename to examples/react/start-basic/app/routes/_layout/_layout-2.tsx index 42ec4ec5b7..3b7dbf2903 100644 --- a/examples/react/start-basic/app/routes/_layoutTest/_layoutTest-2.tsx +++ b/examples/react/start-basic/app/routes/_layout/_layout-2.tsx @@ -1,6 +1,6 @@ import { Link, Outlet, createFileRoute } from '@tanstack/react-router' -export const Route = createFileRoute('/_layoutTest/_layoutTest-2')({ +export const Route = createFileRoute('/_layout/_layout-2')({ component: LayoutComponent, }) diff --git a/examples/react/start-basic/app/routes/_layoutTest/_layoutTest-2/layoutTest-a.tsx b/examples/react/start-basic/app/routes/_layout/_layout-2/layout-a.tsx similarity index 50% rename from examples/react/start-basic/app/routes/_layoutTest/_layoutTest-2/layoutTest-a.tsx rename to examples/react/start-basic/app/routes/_layout/_layout-2/layout-a.tsx index 85a4797b98..61e19b4d9f 100644 --- a/examples/react/start-basic/app/routes/_layoutTest/_layoutTest-2/layoutTest-a.tsx +++ b/examples/react/start-basic/app/routes/_layout/_layout-2/layout-a.tsx @@ -1,10 +1,8 @@ import { createFileRoute } from '@tanstack/react-router' -export const Route = createFileRoute('/_layoutTest/_layoutTest-2/layoutTest-a')( - { - component: LayoutAComponent, - }, -) +export const Route = createFileRoute('/_layout/_layout-2/layout-a')({ + component: LayoutAComponent, +}) function LayoutAComponent() { return
      I'm layout A!
      diff --git a/examples/react/start-basic/app/routes/_layoutTest/_layoutTest-2/layoutTest-b.tsx b/examples/react/start-basic/app/routes/_layout/_layout-2/layout-b.tsx similarity index 50% rename from examples/react/start-basic/app/routes/_layoutTest/_layoutTest-2/layoutTest-b.tsx rename to examples/react/start-basic/app/routes/_layout/_layout-2/layout-b.tsx index 6cf55f5e8d..cceed1fb9a 100644 --- a/examples/react/start-basic/app/routes/_layoutTest/_layoutTest-2/layoutTest-b.tsx +++ b/examples/react/start-basic/app/routes/_layout/_layout-2/layout-b.tsx @@ -1,10 +1,8 @@ import { createFileRoute } from '@tanstack/react-router' -export const Route = createFileRoute('/_layoutTest/_layoutTest-2/layoutTest-b')( - { - component: LayoutBComponent, - }, -) +export const Route = createFileRoute('/_layout/_layout-2/layout-b')({ + component: LayoutBComponent, +}) function LayoutBComponent() { return
      I'm layout B!
      diff --git a/examples/react/start-basic/app/routes/posts.$postId.tsx b/examples/react/start-basic/app/routes/posts.$postId.tsx index 63cd7f8731..0d4d2de8eb 100644 --- a/examples/react/start-basic/app/routes/posts.$postId.tsx +++ b/examples/react/start-basic/app/routes/posts.$postId.tsx @@ -5,7 +5,7 @@ import { NotFound } from '~/components/NotFound' export const Route = createFileRoute('/posts/$postId')({ loader: ({ params: { postId } }) => fetchPost({ data: postId }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostComponent, notFoundComponent: () => { return Post not found diff --git a/examples/react/start-basic/app/routes/posts_.$postId.deep.tsx b/examples/react/start-basic/app/routes/posts_.$postId.deep.tsx index 148223c8df..a1cad68409 100644 --- a/examples/react/start-basic/app/routes/posts_.$postId.deep.tsx +++ b/examples/react/start-basic/app/routes/posts_.$postId.deep.tsx @@ -7,7 +7,7 @@ export const Route = createFileRoute('/posts_/$postId/deep')({ fetchPost({ data: postId, }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostDeepComponent, }) diff --git a/examples/react/start-basic/app/routes/users.$userId.tsx b/examples/react/start-basic/app/routes/users.$userId.tsx index 573377c758..df3f569146 100644 --- a/examples/react/start-basic/app/routes/users.$userId.tsx +++ b/examples/react/start-basic/app/routes/users.$userId.tsx @@ -1,7 +1,8 @@ import { ErrorComponent, createFileRoute } from '@tanstack/react-router' import axios from 'redaxios' import type { ErrorComponentProps } from '@tanstack/react-router' -import { DEPLOY_URL, type User } from '~/utils/users' +import type { User } from '~/utils/users' +import { DEPLOY_URL } from '~/utils/users' import { NotFound } from '~/components/NotFound' export const Route = createFileRoute('/users/$userId')({ diff --git a/examples/react/start-clerk-basic/app/routes/__root.tsx b/examples/react/start-clerk-basic/app/routes/__root.tsx index db877d6e11..ffcca2b011 100644 --- a/examples/react/start-clerk-basic/app/routes/__root.tsx +++ b/examples/react/start-clerk-basic/app/routes/__root.tsx @@ -30,37 +30,39 @@ const fetchClerkAuth = createServerFn({ method: 'GET' }).handler(async () => { }) export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), beforeLoad: async () => { const { user } = await fetchClerkAuth() diff --git a/examples/react/start-clerk-basic/app/routes/_authed/posts.$postId.tsx b/examples/react/start-clerk-basic/app/routes/_authed/posts.$postId.tsx index e4680c6070..039271bb89 100644 --- a/examples/react/start-clerk-basic/app/routes/_authed/posts.$postId.tsx +++ b/examples/react/start-clerk-basic/app/routes/_authed/posts.$postId.tsx @@ -5,7 +5,7 @@ import { fetchPost } from '~/utils/posts.js' export const Route = createFileRoute('/_authed/posts/$postId')({ loader: ({ params: { postId } }) => fetchPost({ data: postId }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostComponent, notFoundComponent: () => { return Post not found diff --git a/examples/react/start-convex-trellaux/app/components/Column.tsx b/examples/react/start-convex-trellaux/app/components/Column.tsx index 220482da64..6f248103df 100644 --- a/examples/react/start-convex-trellaux/app/components/Column.tsx +++ b/examples/react/start-convex-trellaux/app/components/Column.tsx @@ -3,7 +3,7 @@ import invariant from 'tiny-invariant' import { twMerge } from 'tailwind-merge' import { flushSync } from 'react-dom' -import { CONTENT_TYPES, type RenderedItem } from '../types' +import { CONTENT_TYPES } from '../types' import { Icon } from '../icons/icons' import { useDeleteColumnMutation, @@ -13,6 +13,7 @@ import { import { EditableText } from './EditableText' import { NewCard } from './NewCard' import { Card } from './Card' +import type { RenderedItem } from '../types' interface ColumnProps { name: string diff --git a/examples/react/start-convex-trellaux/app/routes/__root.tsx b/examples/react/start-convex-trellaux/app/routes/__root.tsx index e5d97fa7fc..c0f06fa36f 100644 --- a/examples/react/start-convex-trellaux/app/routes/__root.tsx +++ b/examples/react/start-convex-trellaux/app/routes/__root.tsx @@ -21,42 +21,44 @@ import { Loader } from '~/components/Loader' export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), errorComponent: (props) => { return ( diff --git a/examples/react/start-counter/app/client.tsx b/examples/react/start-counter/app/client.tsx index 8d07d8bac1..b14d8aac68 100644 --- a/examples/react/start-counter/app/client.tsx +++ b/examples/react/start-counter/app/client.tsx @@ -1,4 +1,3 @@ -// app/client.tsx /// import { hydrateRoot } from 'react-dom/client' import { StartClient } from '@tanstack/start' @@ -6,4 +5,4 @@ import { createRouter } from './router' const router = createRouter() -hydrateRoot(document!, ) +hydrateRoot(document, ) diff --git a/examples/react/start-counter/app/router.tsx b/examples/react/start-counter/app/router.tsx index dc640c5f4c..d0e2297dce 100644 --- a/examples/react/start-counter/app/router.tsx +++ b/examples/react/start-counter/app/router.tsx @@ -1,4 +1,3 @@ -// app/router.tsx import { createRouter as createTanStackRouter } from '@tanstack/react-router' import { routeTree } from './routeTree.gen' diff --git a/examples/react/start-counter/app/routes/__root.tsx b/examples/react/start-counter/app/routes/__root.tsx index 34ed08e02c..5a48b25d39 100644 --- a/examples/react/start-counter/app/routes/__root.tsx +++ b/examples/react/start-counter/app/routes/__root.tsx @@ -1,22 +1,26 @@ -// app/routes/__root.tsx -import { createRootRoute } from '@tanstack/react-router' -import { Outlet, ScrollRestoration } from '@tanstack/react-router' -import { Meta, Scripts } from '@tanstack/start' import * as React from 'react' +import { + Outlet, + ScrollRestoration, + createRootRoute, +} from '@tanstack/react-router' +import { Meta, Scripts } from '@tanstack/start' export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - { - title: 'TanStack Start Starter', - }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + { + title: 'TanStack Start Starter', + }, + ], + }), component: RootComponent, }) diff --git a/examples/react/start-counter/app/routes/index.tsx b/examples/react/start-counter/app/routes/index.tsx index 3fc16b6677..6a41044351 100644 --- a/examples/react/start-counter/app/routes/index.tsx +++ b/examples/react/start-counter/app/routes/index.tsx @@ -1,4 +1,3 @@ -// app/routes/index.tsx import * as fs from 'node:fs' import { createFileRoute, useRouter } from '@tanstack/react-router' import { createServerFn } from '@tanstack/start' diff --git a/examples/react/start-counter/app/ssr.tsx b/examples/react/start-counter/app/ssr.tsx index c74eeaedc7..f2d33f9030 100644 --- a/examples/react/start-counter/app/ssr.tsx +++ b/examples/react/start-counter/app/ssr.tsx @@ -1,4 +1,3 @@ -// app/ssr.tsx /// import { createStartHandler, diff --git a/examples/react/start-supabase-basic/app.config.ts b/examples/react/start-supabase-basic/app.config.ts index a1ee0f2776..732f04eabe 100644 --- a/examples/react/start-supabase-basic/app.config.ts +++ b/examples/react/start-supabase-basic/app.config.ts @@ -1,3 +1,12 @@ import { defineConfig } from '@tanstack/start/config' +import tsConfigPaths from 'vite-tsconfig-paths' -export default defineConfig({}) +export default defineConfig({ + vite: { + plugins: [ + tsConfigPaths({ + projects: ['./tsconfig.json'], + }), + ], + }, +}) diff --git a/examples/react/start-supabase-basic/app/components/DefaultCatchBoundary.tsx b/examples/react/start-supabase-basic/app/components/DefaultCatchBoundary.tsx index e646acbd45..e14ef8d6c1 100644 --- a/examples/react/start-supabase-basic/app/components/DefaultCatchBoundary.tsx +++ b/examples/react/start-supabase-basic/app/components/DefaultCatchBoundary.tsx @@ -1,12 +1,11 @@ +import * as React from 'react' import { ErrorComponent, Link, rootRouteId, - // ErrorComponentProps, useMatch, useRouter, } from '@tanstack/react-router' -import * as React from 'react' import type { ErrorComponentProps } from '@tanstack/react-router' export function DefaultCatchBoundary({ error }: ErrorComponentProps) { diff --git a/examples/react/start-supabase-basic/app/routes/__root.tsx b/examples/react/start-supabase-basic/app/routes/__root.tsx index a4b1784ca9..184c977f68 100644 --- a/examples/react/start-supabase-basic/app/routes/__root.tsx +++ b/examples/react/start-supabase-basic/app/routes/__root.tsx @@ -15,7 +15,7 @@ import { getSupabaseServerClient } from '../utils/supabase' const fetchUser = createServerFn({ method: 'GET' }).handler(async () => { const supabase = await getSupabaseServerClient() - const { data, error } = await supabase.auth.getUser() + const { data, error: _error } = await supabase.auth.getUser() if (!data.user?.email) { return null @@ -25,42 +25,44 @@ const fetchUser = createServerFn({ method: 'GET' }).handler(async () => { }) export const Route = createRootRoute({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), beforeLoad: async () => { const user = await fetchUser() diff --git a/examples/react/start-supabase-basic/app/routes/_authed/posts.$postId.tsx b/examples/react/start-supabase-basic/app/routes/_authed/posts.$postId.tsx index 87d52ffcc6..4dd11756a8 100644 --- a/examples/react/start-supabase-basic/app/routes/_authed/posts.$postId.tsx +++ b/examples/react/start-supabase-basic/app/routes/_authed/posts.$postId.tsx @@ -1,11 +1,11 @@ import { ErrorComponent, createFileRoute } from '@tanstack/react-router' -import { NotFound } from '../../components/NotFound' -import { fetchPost } from '../../utils/posts' import type { ErrorComponentProps } from '@tanstack/react-router' +import { NotFound } from '~/components/NotFound' +import { fetchPost } from '~/utils/posts' export const Route = createFileRoute('/_authed/posts/$postId')({ loader: ({ params: { postId } }) => fetchPost({ data: postId }), - errorComponent: PostErrorComponent as any, + errorComponent: PostErrorComponent, component: PostComponent, notFoundComponent: () => { return Post not found diff --git a/examples/react/start-supabase-basic/package.json b/examples/react/start-supabase-basic/package.json index b6e2da2723..97a679cb4e 100644 --- a/examples/react/start-supabase-basic/package.json +++ b/examples/react/start-supabase-basic/package.json @@ -28,6 +28,7 @@ "autoprefixer": "^10.4.20", "postcss": "^8.4.49", "tailwindcss": "^3.4.14", - "typescript": "^5.6.2" + "typescript": "^5.6.2", + "vite-tsconfig-paths": "^5.1.2" } } diff --git a/examples/react/start-supabase-basic/tailwind.config.ts b/examples/react/start-supabase-basic/tailwind.config.ts deleted file mode 100644 index d0253e59a8..0000000000 --- a/examples/react/start-supabase-basic/tailwind.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { Config } from 'tailwindcss' - -export default { - content: [], - theme: { - extend: {}, - }, - plugins: [], -} satisfies Config diff --git a/examples/react/start-trellaux/app/components/Board.tsx b/examples/react/start-trellaux/app/components/Board.tsx index 5c7f388e40..1fe1179abf 100644 --- a/examples/react/start-trellaux/app/components/Board.tsx +++ b/examples/react/start-trellaux/app/components/Board.tsx @@ -2,9 +2,9 @@ import { useCallback, useMemo, useRef } from 'react' import invariant from 'tiny-invariant' import { useSuspenseQuery } from '@tanstack/react-query' import { boardQueries, useUpdateBoardMutation } from '../queries.js' -import { type Column } from '../db/schema.js' import { NewColumn } from './NewColumn.js' import { Column as ColumnComponent } from './Column.js' +import type { Column } from '../db/schema.js' import { EditableText } from '~/components/EditableText.js' export function Board({ boardId }: { boardId: string }) { diff --git a/examples/react/start-trellaux/app/components/Column.tsx b/examples/react/start-trellaux/app/components/Column.tsx index 220482da64..6f248103df 100644 --- a/examples/react/start-trellaux/app/components/Column.tsx +++ b/examples/react/start-trellaux/app/components/Column.tsx @@ -3,7 +3,7 @@ import invariant from 'tiny-invariant' import { twMerge } from 'tailwind-merge' import { flushSync } from 'react-dom' -import { CONTENT_TYPES, type RenderedItem } from '../types' +import { CONTENT_TYPES } from '../types' import { Icon } from '../icons/icons' import { useDeleteColumnMutation, @@ -13,6 +13,7 @@ import { import { EditableText } from './EditableText' import { NewCard } from './NewCard' import { Card } from './Card' +import type { RenderedItem } from '../types' interface ColumnProps { name: string diff --git a/examples/react/start-trellaux/app/components/NewColumn.tsx b/examples/react/start-trellaux/app/components/NewColumn.tsx index 52e250b781..34a024a86a 100644 --- a/examples/react/start-trellaux/app/components/NewColumn.tsx +++ b/examples/react/start-trellaux/app/components/NewColumn.tsx @@ -3,7 +3,6 @@ import invariant from 'tiny-invariant' import { Icon } from '../icons/icons' import { useCreateColumnMutation } from '../queries' -import { newColumnSchema } from '../db/schema' import { CancelButton } from '~/components/CancelButton' import { SaveButton } from '~/components/SaveButton' diff --git a/examples/react/start-trellaux/app/routes/__root.tsx b/examples/react/start-trellaux/app/routes/__root.tsx index e5d97fa7fc..c0f06fa36f 100644 --- a/examples/react/start-trellaux/app/routes/__root.tsx +++ b/examples/react/start-trellaux/app/routes/__root.tsx @@ -21,42 +21,44 @@ import { Loader } from '~/components/Loader' export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()({ - meta: () => [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - ...seo({ - title: - 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', - description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, - }), - ], - links: () => [ - { rel: 'stylesheet', href: appCss }, - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon-16x16.png', - }, - { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, - { rel: 'icon', href: '/favicon.ico' }, - ], + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + ...seo({ + title: + 'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework', + description: `TanStack Start is a type-safe, client-first, full-stack React framework. `, + }), + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { + rel: 'apple-touch-icon', + sizes: '180x180', + href: '/apple-touch-icon.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + href: '/favicon-32x32.png', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '16x16', + href: '/favicon-16x16.png', + }, + { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' }, + { rel: 'icon', href: '/favicon.ico' }, + ], + }), errorComponent: (props) => { return ( diff --git a/packages/react-router/src/route.ts b/packages/react-router/src/route.ts index 701de16bae..7be86a89cb 100644 --- a/packages/react-router/src/route.ts +++ b/packages/react-router/src/route.ts @@ -434,7 +434,10 @@ export interface UpdatableRouteOptions< TLoaderDeps >, ) => void - meta?: (ctx: { + headers?: (ctx: { + loaderData: ResolveLoaderData + }) => Record + head?: (ctx: { matches: Array< RouteMatch< TRouteId, @@ -466,13 +469,12 @@ export interface UpdatableRouteOptions< TLoaderDeps > params: ResolveAllParamsFromParent - loaderData: ResolveLoaderData - }) => Array - links?: () => Array - scripts?: () => Array - headers?: (ctx: { - loaderData: ResolveLoaderData - }) => Record + loaderData: ResolveLoaderData | undefined + }) => { + links?: Array | undefined + scripts?: Array | undefined + meta?: Array | undefined + } ssr?: boolean } diff --git a/packages/react-router/src/router.ts b/packages/react-router/src/router.ts index 54a7fd448b..20c33ec42a 100644 --- a/packages/react-router/src/router.ts +++ b/packages/react-router/src/router.ts @@ -1298,25 +1298,30 @@ export class Router< : loaderDeps, invalid: false, preload: false, - links: route.options.links?.(), - scripts: route.options.scripts?.(), + links: undefined, + scripts: undefined, + meta: undefined, staticData: route.options.staticData || {}, loadPromise: createControlledPromise(), fullPath: route.fullPath, } } - // If it's already a success, update the meta and headers + const headFnContent = route.options.head?.({ + matches, + match, + params: match.params, + loaderData: match.loaderData ?? undefined, + }) + + match.links = headFnContent?.links + match.scripts = headFnContent?.scripts + match.meta = headFnContent?.meta + + // If it's already a success, update the headers // These may get updated again if the match is refreshed // due to being stale if (match.status === 'success') { - match.meta = route.options.meta?.({ - matches, - match, - params: match.params, - loaderData: match.loaderData, - }) - match.headers = route.options.headers?.({ loaderData: match.loaderData, }) @@ -2516,12 +2521,13 @@ export class Router< await potentialPendingMinPromise() - const meta = route.options.meta?.({ + const headFnContent = route.options.head?.({ matches, match: this.getMatch(matchId)!, params: this.getMatch(matchId)!.params, loaderData, }) + const meta = headFnContent?.meta const headers = route.options.headers?.({ loaderData, diff --git a/packages/start/src/client/serialization.tsx b/packages/start/src/client/serialization.tsx index 2f0091264a..067c18a20f 100644 --- a/packages/start/src/client/serialization.tsx +++ b/packages/start/src/client/serialization.tsx @@ -111,20 +111,17 @@ export function afterHydrate({ router }: { router: AnyRouter }) { } } - const meta = - match.status === 'success' - ? route.options.meta?.({ - matches: router.state.matches, - match, - params: match.params, - loaderData: match.loaderData, - }) - : undefined + const headFnContent = route.options.head?.({ + matches: router.state.matches, + match, + params: match.params, + loaderData: match.loaderData, + }) Object.assign(match, { - meta, - links: route.options.links?.(), - scripts: route.options.scripts?.(), + meta: headFnContent?.meta, + links: headFnContent?.links, + scripts: headFnContent?.scripts, }) }) } diff --git a/packages/start/src/client/tests/index.test.tsx b/packages/start/src/client/tests/index.test.tsx index b973d55cc5..82ebf9bb88 100644 --- a/packages/start/src/client/tests/index.test.tsx +++ b/packages/start/src/client/tests/index.test.tsx @@ -17,14 +17,18 @@ describe('ssr scripts', () => { test('it works', async () => { const rootRoute = createRootRoute({ // loader: () => new Promise((r) => setTimeout(r, 1)), - scripts: () => [ - { - src: 'script.js', - }, - { - src: 'script2.js', - }, - ], + head: () => { + return { + scripts: [ + { + src: 'script.js', + }, + { + src: 'script2.js', + }, + ], + } + }, component: () => { return }, @@ -34,11 +38,15 @@ describe('ssr scripts', () => { path: '/', getParentRoute: () => rootRoute, // loader: () => new Promise((r) => setTimeout(r, 2)), - scripts: () => [ - { - src: 'script3.js', - }, - ], + head: () => { + return { + scripts: [ + { + src: 'script3.js', + }, + ], + } + }, }) const router = createRouter({ @@ -77,19 +85,27 @@ describe('ssr meta', () => { new Promise((r) => setTimeout(r, 1)).then(() => ({ description: 'Root', })), - meta: ({ loaderData }) => [ - { - title: 'Root', - }, - { - name: 'description', - content: loaderData.description, - }, - { - name: 'image', - content: 'image.jpg', - }, - ], + head: ({ loaderData }) => { + if (!loaderData) { + return {} + } + + return { + meta: [ + { + title: 'Root', + }, + { + name: 'description', + content: loaderData.description, + }, + { + name: 'image', + content: 'image.jpg', + }, + ], + } + }, component: () => { return }, @@ -102,19 +118,27 @@ describe('ssr meta', () => { new Promise((r) => setTimeout(r, 2)).then(() => ({ description: 'Index', })), - meta: ({ loaderData }) => [ - { - title: 'Index', - }, - { - name: 'description', - content: loaderData.description, - }, - { - name: 'last-modified', - content: '2021-10-10', - }, - ], + head: ({ loaderData }) => { + if (!loaderData) { + return {} + } + + return { + meta: [ + { + title: 'Index', + }, + { + name: 'description', + content: loaderData.description, + }, + { + name: 'last-modified', + content: '2021-10-10', + }, + ], + } + }, }) const router = createRouter({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29a4a6b036..b7422d060d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1781,10 +1781,10 @@ importers: version: 18.3.1 html-webpack-plugin: specifier: ^5.6.3 - version: 5.6.3(@rspack/core@1.1.1(@swc/helpers@0.5.15))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)) + version: 5.6.3(@rspack/core@1.1.1(@swc/helpers@0.5.15))(webpack@5.96.1) swc-loader: specifier: ^0.2.6 - version: 0.2.6(@swc/core@1.9.2(@swc/helpers@0.5.15))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)) + version: 0.2.6(@swc/core@1.9.2(@swc/helpers@0.5.15))(webpack@5.96.1) typescript: specifier: ^5.6.2 version: 5.6.3 @@ -2674,6 +2674,9 @@ importers: typescript: specifier: ^5.6.2 version: 5.6.3 + vite-tsconfig-paths: + specifier: ^5.1.2 + version: 5.1.2(typescript@5.6.3)(vite@5.4.11(@types/node@22.9.0)(terser@5.36.0)) examples/react/start-trellaux: dependencies: @@ -2932,7 +2935,7 @@ importers: version: 4.3.3(vite@5.4.11(@types/node@22.9.0)(terser@5.36.0)) html-webpack-plugin: specifier: ^5.6.0 - version: 5.6.3(@rspack/core@1.1.1(@swc/helpers@0.5.15))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)) + version: 5.6.3(@rspack/core@1.1.1(@swc/helpers@0.5.15))(webpack@5.96.1) react: specifier: ^18.3.1 version: 18.3.1 @@ -2941,7 +2944,7 @@ importers: version: 18.3.1(react@18.3.1) swc-loader: specifier: ^0.2.6 - version: 0.2.6(@swc/core@1.9.2(@swc/helpers@0.5.15))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)) + version: 0.2.6(@swc/core@1.9.2(@swc/helpers@0.5.15))(webpack@5.96.1) typescript: specifier: ^5.6.2 version: 5.6.3 @@ -13849,17 +13852,17 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4))': + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.96.1)': dependencies: webpack: 5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1) - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4))': + '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.96.1)': dependencies: webpack: 5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1) - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1))(webpack-dev-server@5.1.0(webpack-cli@5.1.4)(webpack@5.96.1))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4))': + '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.1.0)(webpack@5.96.1)': dependencies: webpack: 5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1) @@ -15918,7 +15921,7 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.6.3(@rspack/core@1.1.1(@swc/helpers@0.5.15))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)): + html-webpack-plugin@5.6.3(@rspack/core@1.1.1(@swc/helpers@0.5.15))(webpack@5.96.1): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -18211,7 +18214,7 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - swc-loader@0.2.6(@swc/core@1.9.2(@swc/helpers@0.5.15))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)): + swc-loader@0.2.6(@swc/core@1.9.2(@swc/helpers@0.5.15))(webpack@5.96.1): dependencies: '@swc/core': 1.9.2(@swc/helpers@0.5.15) '@swc/counter': 0.1.3 @@ -18281,26 +18284,26 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 - terser-webpack-plugin@5.3.10(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)): + terser-webpack-plugin@5.3.10(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.36.0 - webpack: 5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4) + webpack: 5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0) optionalDependencies: '@swc/core': 1.9.2(@swc/helpers@0.5.15) esbuild: 0.24.0 - terser-webpack-plugin@5.3.10(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)): + terser-webpack-plugin@5.3.10(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack@5.96.1): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.36.0 - webpack: 5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0) + webpack: 5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4) optionalDependencies: '@swc/core': 1.9.2(@swc/helpers@0.5.15) esbuild: 0.24.0 @@ -18958,9 +18961,9 @@ snapshots: webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1): dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.96.1))(webpack-dev-server@5.1.0(webpack-cli@5.1.4)(webpack@5.96.1))(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)) + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.96.1) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.96.1) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.1.0)(webpack@5.96.1) colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.5 @@ -18974,7 +18977,7 @@ snapshots: optionalDependencies: webpack-dev-server: 5.1.0(webpack-cli@5.1.4)(webpack@5.96.1) - webpack-dev-middleware@7.4.2(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)): + webpack-dev-middleware@7.4.2(webpack@5.96.1): dependencies: colorette: 2.0.20 memfs: 4.14.0 @@ -19013,7 +19016,7 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)) + webpack-dev-middleware: 7.4.2(webpack@5.96.1) ws: 8.18.0 optionalDependencies: webpack: 5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4) @@ -19086,7 +19089,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4)) + terser-webpack-plugin: 5.3.10(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack@5.96.1) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: