Skip to content

Commit

Permalink
fix(react-router): ensure links and scripts are available on routes c…
Browse files Browse the repository at this point in the history
…reated with `createRoute` (#2854)

* ensure that links and scripts are available on route, routes created with createFileRoute work routes created with createRoute did not

* test(react-router): check for head fn update

---------

Co-authored-by: SeanCassiere <33615041+SeanCassiere@users.noreply.github.com>
  • Loading branch information
GregoryCollett and SeanCassiere authored Dec 6, 2024
1 parent 0a58c0f commit d44912a
Show file tree
Hide file tree
Showing 2 changed files with 198 additions and 1 deletion.
4 changes: 4 additions & 0 deletions packages/react-router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2580,6 +2580,8 @@ export class Router<
loaderData,
})
const meta = headFnContent?.meta
const links = headFnContent?.links
const scripts = headFnContent?.scripts

const headers = route.options.headers?.({
loaderData,
Expand All @@ -2593,6 +2595,8 @@ export class Router<
updatedAt: Date.now(),
loaderData,
meta,
links,
scripts,
headers,
}))
} catch (e) {
Expand Down
195 changes: 194 additions & 1 deletion packages/react-router/tests/route.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { afterEach, describe, expect, it, test, vi } from 'vitest'
import { cleanup, render, screen } from '@testing-library/react'

import {
Expand Down Expand Up @@ -193,3 +193,196 @@ describe('onEnter event', () => {
expect(fn).toHaveBeenCalledWith({ foo: 'bar' })
})
})

describe('route.head', () => {
test('meta', async () => {
const rootRoute = createRootRoute({
head: () => ({
meta: [
{ title: 'Root' },
{
charSet: 'utf-8',
},
],
}),
})
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
head: () => ({
meta: [{ title: 'Index' }],
}),
component: () => <div>Index</div>,
})
const routeTree = rootRoute.addChildren([indexRoute])
const router = createRouter({ routeTree })
render(<RouterProvider router={router} />)
const indexElem = await screen.findByText('Index')
expect(indexElem).toBeInTheDocument()

const metaState = router.state.matches.map((m) => m.meta)
expect(metaState).toEqual([
[
{ title: 'Root' },
{
charSet: 'utf-8',
},
],
[{ title: 'Index' }],
])
})

test('meta w/ loader', async () => {
const rootRoute = createRootRoute({
head: () => ({
meta: [
{ title: 'Root' },
{
charSet: 'utf-8',
},
],
}),
})
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
head: () => ({
meta: [{ title: 'Index' }],
}),
loader: async () => {
await new Promise((resolve) => setTimeout(resolve, 200))
},
component: () => <div>Index</div>,
})
const routeTree = rootRoute.addChildren([indexRoute])
const router = createRouter({ routeTree })
render(<RouterProvider router={router} />)
const indexElem = await screen.findByText('Index')
expect(indexElem).toBeInTheDocument()

const metaState = router.state.matches.map((m) => m.meta)
expect(metaState).toEqual([
[
{ title: 'Root' },
{
charSet: 'utf-8',
},
],
[{ title: 'Index' }],
])
})

test('scripts', async () => {
const rootRoute = createRootRoute({
head: () => ({
scripts: [{ src: 'root.js' }, { src: 'root2.js' }],
}),
})
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
head: () => ({
scripts: [{ src: 'index.js' }],
}),
component: () => <div>Index</div>,
})
const routeTree = rootRoute.addChildren([indexRoute])
const router = createRouter({ routeTree })
render(<RouterProvider router={router} />)
const indexElem = await screen.findByText('Index')
expect(indexElem).toBeInTheDocument()

const scriptsState = router.state.matches.map((m) => m.scripts)
expect(scriptsState).toEqual([
[{ src: 'root.js' }, { src: 'root2.js' }],
[{ src: 'index.js' }],
])
})

test('scripts w/ loader', async () => {
const rootRoute = createRootRoute({
head: () => ({
scripts: [{ src: 'root.js' }, { src: 'root2.js' }],
}),
})
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
head: () => ({
scripts: [{ src: 'index.js' }],
}),
loader: async () => {
await new Promise((resolve) => setTimeout(resolve, 200))
},
component: () => <div>Index</div>,
})
const routeTree = rootRoute.addChildren([indexRoute])
const router = createRouter({ routeTree })
render(<RouterProvider router={router} />)
const indexElem = await screen.findByText('Index')
expect(indexElem).toBeInTheDocument()

const scriptsState = router.state.matches.map((m) => m.scripts)
expect(scriptsState).toEqual([
[{ src: 'root.js' }, { src: 'root2.js' }],
[{ src: 'index.js' }],
])
})

test('links', async () => {
const rootRoute = createRootRoute({
head: () => ({
links: [{ href: 'root.css' }, { href: 'root2.css' }],
}),
})
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
head: () => ({
links: [{ href: 'index.css' }],
}),
component: () => <div>Index</div>,
})
const routeTree = rootRoute.addChildren([indexRoute])
const router = createRouter({ routeTree })
render(<RouterProvider router={router} />)
const indexElem = await screen.findByText('Index')
expect(indexElem).toBeInTheDocument()

const linksState = router.state.matches.map((m) => m.links)
expect(linksState).toEqual([
[{ href: 'root.css' }, { href: 'root2.css' }],
[{ href: 'index.css' }],
])
})

test('links w/loader', async () => {
const rootRoute = createRootRoute({
head: () => ({
links: [{ href: 'root.css' }, { href: 'root2.css' }],
}),
})
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
head: () => ({
links: [{ href: 'index.css' }],
}),
loader: async () => {
await new Promise((resolve) => setTimeout(resolve, 200))
},
component: () => <div>Index</div>,
})
const routeTree = rootRoute.addChildren([indexRoute])
const router = createRouter({ routeTree })
render(<RouterProvider router={router} />)
const indexElem = await screen.findByText('Index')
expect(indexElem).toBeInTheDocument()

const linksState = router.state.matches.map((m) => m.links)
expect(linksState).toEqual([
[{ href: 'root.css' }, { href: 'root2.css' }],
[{ href: 'index.css' }],
])
})
})

0 comments on commit d44912a

Please sign in to comment.