Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(start): move scripts,links, and meta to the head #2571

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
26 changes: 14 additions & 12 deletions docs/framework/react/start/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,18 +204,20 @@ import { Body, Head, Html, 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,
})

Expand Down
1 change: 1 addition & 0 deletions e2e/start/basic-auth/app/client.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// <reference types="vinxi/types/client" />
import { hydrateRoot } from 'react-dom/client'
import { StartClient } from '@tanstack/start'
import { createRouter } from './router'
Expand Down
Original file line number Diff line number Diff line change
@@ -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()
Expand Down
74 changes: 38 additions & 36 deletions e2e/start/basic-auth/app/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,42 +34,44 @@ const fetchUser = createServerFn('GET', 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()

Expand Down
3 changes: 1 addition & 2 deletions e2e/start/basic-auth/app/routes/_authed.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn, json } from '@tanstack/start'
import { Auth } from '../components/Auth'
import { createServerFn } from '@tanstack/start'
import { hashPassword, prismaClient } from '~/utils/prisma'
import { Login } from '~/components/Login'
import { useAppSession } from '~/utils/session'
Expand Down
1 change: 0 additions & 1 deletion e2e/start/basic-auth/app/routes/signup.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
import { createServerFn, useServerFn } from '@tanstack/start'
import { updateSession } from 'vinxi/http'
import { hashPassword, prismaClient } from '~/utils/prisma'
import { useMutation } from '~/hooks/useMutation'
import { Auth } from '~/components/Auth'
Expand Down
1 change: 1 addition & 0 deletions e2e/start/basic-react-query/app/client.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// <reference types="vinxi/types/client" />
import { hydrateRoot } from 'react-dom/client'
import { StartClient } from '@tanstack/start'
import { createRouter } from './router'
Expand Down
Original file line number Diff line number Diff line change
@@ -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()
Expand Down
75 changes: 38 additions & 37 deletions e2e/start/basic-react-query/app/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<RootDocument>
Expand Down
10 changes: 4 additions & 6 deletions e2e/start/basic-react-query/app/routes/posts.$postId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <NotFound>Post not found</NotFound>
},
Expand Down
2 changes: 1 addition & 1 deletion e2e/start/basic-react-query/app/routes/posts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const Route = createFileRoute('/posts')({
loader: async ({ context }) => {
await context.queryClient.ensureQueryData(postsQueryOptions())
},
meta: () => [{ title: 'Posts' }],
head: () => ({ meta: [{ title: 'Posts' }] }),
component: PostsComponent,
})

Expand Down
10 changes: 4 additions & 6 deletions e2e/start/basic-react-query/app/routes/posts_.$postId.deep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})

Expand Down
1 change: 1 addition & 0 deletions e2e/start/basic-rsc/app/client.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// <reference types="vinxi/types/client" />
import { hydrateRoot } from 'react-dom/client'
import { StartClient } from '@tanstack/start'
import { createRouter } from './router'
Expand Down
Original file line number Diff line number Diff line change
@@ -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()
Expand Down
74 changes: 38 additions & 36 deletions e2e/start/basic-rsc/app/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<RootDocument>
Expand Down
Loading
Loading