Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/router-core/src/load-matches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,9 @@ const executeHead = (
}

return Promise.all([
route.options.head?.(assetContext),
typeof route.options.head === 'function'
? route.options.head(assetContext)
: route.options.head,
route.options.scripts?.(assetContext),
route.options.headers?.(assetContext),
]).then(([headFnContent, scripts, headers]) => {
Expand Down
45 changes: 26 additions & 19 deletions packages/router-core/src/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1383,25 +1383,32 @@ export interface UpdatableRouteOptions<
TLoaderDeps
>,
) => Awaitable<Record<string, string> | undefined>
head?: (
ctx: AssetFnContextOptions<
TRouteId,
TFullPath,
TParentRoute,
TParams,
TSearchValidator,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps
>,
) => Awaitable<{
links?: AnyRouteMatch['links']
scripts?: AnyRouteMatch['headScripts']
meta?: AnyRouteMatch['meta']
styles?: AnyRouteMatch['styles']
}>
head?:
| ((
ctx: AssetFnContextOptions<
TRouteId,
TFullPath,
TParentRoute,
TParams,
TSearchValidator,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps
>,
) => Awaitable<{
links?: AnyRouteMatch['links']
scripts?: AnyRouteMatch['headScripts']
meta?: AnyRouteMatch['meta']
styles?: AnyRouteMatch['styles']
}>)
| {
links?: AnyRouteMatch['links']
scripts?: AnyRouteMatch['headScripts']
meta?: AnyRouteMatch['meta']
styles?: AnyRouteMatch['styles']
}
scripts?: (
ctx: AssetFnContextOptions<
TRouteId,
Expand Down
5 changes: 4 additions & 1 deletion packages/router-core/src/ssr/ssr-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,10 @@ export async function hydrate(router: AnyRouter): Promise<any> {
params: match.params,
loaderData: match.loaderData,
}
const headFnContent = await route.options.head?.(assetContext)
const headFnContent =
typeof route.options.head === 'function'
? await route.options.head(assetContext)
: route.options.head

const scripts = await route.options.scripts?.(assetContext)

Expand Down
59 changes: 59 additions & 0 deletions packages/router-core/tests/load.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1851,6 +1851,65 @@ describe('head execution', () => {
expect(rootMatch?.error).toBeUndefined()
})
})

test('accepts a static object for head instead of a function', async () => {
const staticHead = {
meta: [{ title: 'Static Title' }],
links: [{ rel: 'icon', href: '/favicon.ico' }],
}

const rootRoute = new BaseRootRoute({
head: staticHead,
})
const testRoute = new BaseRoute({
getParentRoute: () => rootRoute,
path: '/test',
})
const routeTree = rootRoute.addChildren([testRoute])
const router = new RouterCore({
routeTree,
history: createMemoryHistory({ initialEntries: ['/test'] }),
})

await router.load()

const match = router.state.matches.find(
(m) => m.routeId === rootRoute.id,
)
expect(match?.meta).toEqual([{ title: 'Static Title' }])
expect(match?.links).toEqual([{ rel: 'icon', href: '/favicon.ico' }])
})

test('static head object and function head work together in route hierarchy', async () => {
const rootRoute = new BaseRootRoute({
head: {
meta: [{ charSet: 'UTF-8' }],
},
})
const childRoute = new BaseRoute({
getParentRoute: () => rootRoute,
path: '/child',
head: () => ({
meta: [{ title: 'Child Page' }],
}),
})
const routeTree = rootRoute.addChildren([childRoute])
const router = new RouterCore({
routeTree,
history: createMemoryHistory({ initialEntries: ['/child'] }),
})

await router.load()

const rootMatch = router.state.matches.find(
(m) => m.routeId === rootRoute.id,
)
const childMatch = router.state.matches.find(
(m) => m.routeId === childRoute.id,
)
expect(rootMatch?.meta).toEqual([{ charSet: 'UTF-8' }])
expect(childMatch?.meta).toEqual([{ title: 'Child Page' }])
})
})

describe('params.parse notFound', () => {
Expand Down
Loading