// src/start.ts
import { createStart, createMiddleware } from '@tanstack/react-start'
import {
getRequestHeader,
getCookie,
setCookie,
} from '@tanstack/react-start/server'
const localeTzMiddleware = createMiddleware().server(async ({ next }) => {
const header = getRequestHeader('accept-language')
const headerLocale = header?.split(',')[0] || 'en-US'
const cookieLocale = getCookie('locale')
const cookieTz = getCookie('tz') // set by client later (see Strategy 2)
const locale = cookieLocale || headerLocale
const timeZone = cookieTz || 'UTC' // deterministic until client sends tz
// Persist locale for subsequent requests (optional)
setCookie('locale', locale, { path: '/', maxAge: 60 * 60 * 24 * 365 })
return next({ context: { locale, timeZone } })
})
export const startInstance = createStart(() => ({
requestMiddleware: [localeTzMiddleware],
}))
// src/start.ts
import { createStart, createMiddleware } from '@tanstack/react-start'
import {
getRequestHeader,
getCookie,
setCookie,
} from '@tanstack/react-start/server'
const localeTzMiddleware = createMiddleware().server(async ({ next }) => {
const header = getRequestHeader('accept-language')
const headerLocale = header?.split(',')[0] || 'en-US'
const cookieLocale = getCookie('locale')
const cookieTz = getCookie('tz') // set by client later (see Strategy 2)
const locale = cookieLocale || headerLocale
const timeZone = cookieTz || 'UTC' // deterministic until client sends tz
// Persist locale for subsequent requests (optional)
setCookie('locale', locale, { path: '/', maxAge: 60 * 60 * 24 * 365 })
return next({ context: { locale, timeZone } })
})
export const startInstance = createStart(() => ({
requestMiddleware: [localeTzMiddleware],
}))
// src/routes/index.tsx (example)
import * as React from 'react'
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { getCookie } from '@tanstack/react-start/server'
export const getServerNow = createServerFn().handler(async () => {
const locale = getCookie('locale') || 'en-US'
const timeZone = getCookie('tz') || 'UTC'
return new Intl.DateTimeFormat(locale, {
dateStyle: 'medium',
timeStyle: 'short',
timeZone,
}).format(new Date())
})
export const Route = createFileRoute('/')({
loader: () => getServerNow(),
component: () => {
const serverNow = Route.useLoaderData() as string
return <time dateTime={serverNow}>{serverNow}</time>
},
})
// src/routes/index.tsx (example)
import * as React from 'react'
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { getCookie } from '@tanstack/react-start/server'
export const getServerNow = createServerFn().handler(async () => {
const locale = getCookie('locale') || 'en-US'
const timeZone = getCookie('tz') || 'UTC'
return new Intl.DateTimeFormat(locale, {
dateStyle: 'medium',
timeStyle: 'short',
timeZone,
}).format(new Date())
})
export const Route = createFileRoute('/')({
loader: () => getServerNow(),
component: () => {
const serverNow = Route.useLoaderData() as string
return <time dateTime={serverNow}>{serverNow}</time>
},
})
import * as React from 'react'
import { ClientOnly } from '@tanstack/react-router'
function SetTimeZoneCookie() {
React.useEffect(() => {
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone
document.cookie = `tz=${tz}; path=/; max-age=31536000`
}, [])
return null
}
export function AppBoot() {
return (
<ClientOnly fallback={null}>
<SetTimeZoneCookie />
</ClientOnly>
)
}
import * as React from 'react'
import { ClientOnly } from '@tanstack/react-router'
function SetTimeZoneCookie() {
React.useEffect(() => {
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone
document.cookie = `tz=${tz}; path=/; max-age=31536000`
}, [])
return null
}
export function AppBoot() {
return (
<ClientOnly fallback={null}>
<SetTimeZoneCookie />
</ClientOnly>
)
}
import { ClientOnly } from '@tanstack/react-router'
;<ClientOnly fallback={<span>—</span>}>
<RelativeTime ts={someTs} />
</ClientOnly>
import { ClientOnly } from '@tanstack/react-router'
;<ClientOnly fallback={<span>—</span>}>
<RelativeTime ts={someTs} />
</ClientOnly>
export const Route = createFileRoute('/unstable')({
ssr: 'data-only', // or false
component: () => <ExpensiveViz />,
})
export const Route = createFileRoute('/unstable')({
ssr: 'data-only', // or false
component: () => <ExpensiveViz />,
})
<time suppressHydrationWarning>{new Date().toLocaleString()}</time>
<time suppressHydrationWarning>{new Date().toLocaleString()}</time>
See also: Execution Model, Code Execution Patterns, Selective SSR, Server Functions
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.
