diff --git a/packages/one/src/fork/getStateFromPath.ts b/packages/one/src/fork/getStateFromPath.ts
index 01cbeaf547..caecc209d3 100644
--- a/packages/one/src/fork/getStateFromPath.ts
+++ b/packages/one/src/fork/getStateFromPath.ts
@@ -461,6 +461,7 @@ const matchAgainstConfigs = (remaining: string, configs: RouteConfig[]) => {
}, {})
if (params && Object.keys(params).length) {
+ Object.assign(allParams, params) // @modified: let page access layout params
return { name, params }
}
diff --git a/tests/test/app/layouts/index.tsx b/tests/test/app/layouts/index.tsx
new file mode 100644
index 0000000000..15df3540b8
--- /dev/null
+++ b/tests/test/app/layouts/index.tsx
@@ -0,0 +1,17 @@
+import { Link } from 'one'
+
+export default function LayoutTestsIndex() {
+ return (
+ <>
+
+ Nested layout with slug layout folder
+
+ {/*
+ Nested layout with layout and page params
+ */}
+ >
+ )
+}
diff --git a/tests/test/app/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]/_layout.tsx b/tests/test/app/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]/_layout.tsx
new file mode 100644
index 0000000000..a00fcb279f
--- /dev/null
+++ b/tests/test/app/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]/_layout.tsx
@@ -0,0 +1,13 @@
+import { Slot, useParams } from 'one'
+import { Text } from 'tamagui'
+
+export default function LayoutWithParam() {
+ const params = useParams()
+
+ return (
+ <>
+ {JSON.stringify(params)}
+
+ >
+ )
+}
diff --git a/tests/test/app/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]/index+ssr.tsx b/tests/test/app/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]/index+ssr.tsx
new file mode 100644
index 0000000000..a742a1b642
--- /dev/null
+++ b/tests/test/app/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]/index+ssr.tsx
@@ -0,0 +1,12 @@
+import { Link, useParams, usePathname } from 'one'
+import { View, Text } from 'tamagui'
+
+export default function HooksTestingPage() {
+ const params = useParams()
+
+ return (
+
+ {JSON.stringify(params)}
+
+ )
+}
diff --git a/tests/test/routes.d.ts b/tests/test/routes.d.ts
index f9e49e3048..0cb6bb33ed 100644
--- a/tests/test/routes.d.ts
+++ b/tests/test/routes.d.ts
@@ -6,9 +6,9 @@ import type { OneRouter } from 'one'
declare module 'one' {
export namespace OneRouter {
export interface __routes extends Record {
- StaticRoutes: `/` | `/(auth-guard)` | `/(auth-guard)/auth-guard` | `/(blog)` | `/(blog)/blog/my-first-post` | `/(marketing)/about` | `/(sub-page-group)` | `/(sub-page-group)/sub-page` | `/(sub-page-group)/sub-page/sub` | `/(sub-page-group)/sub-page/sub2` | `/_sitemap` | `/about` | `/auth-guard` | `/blog/my-first-post` | `/expo-video` | `/hooks` | `/hooks/contents` | `/hooks/contents/page-1` | `/hooks/contents/page-2` | `/loader` | `/loader/other` | `/middleware` | `/not-found/deep/test` | `/not-found/fallback/test` | `/not-found/test` | `/server-data` | `/sheet` | `/spa/spapage` | `/ssr/basic` | `/sub-page` | `/sub-page/sub` | `/sub-page/sub2` | `/web-extensions`
- DynamicRoutes: `/not-found/+not-found` | `/not-found/deep/+not-found` | `/routes/subpath/${string}` | `/spa/${OneRouter.SingleRoutePart}` | `/ssr/${OneRouter.SingleRoutePart}` | `/ssr/${string}`
- DynamicRouteTemplate: `/not-found/+not-found` | `/not-found/deep/+not-found` | `/routes/subpath/[...subpath]` | `/spa/[spaparams]` | `/ssr/[...rest]` | `/ssr/[param]`
+ StaticRoutes: `/` | `/(auth-guard)` | `/(auth-guard)/auth-guard` | `/(blog)` | `/(blog)/blog/my-first-post` | `/(marketing)/about` | `/(sub-page-group)` | `/(sub-page-group)/sub-page` | `/(sub-page-group)/sub-page/sub` | `/(sub-page-group)/sub-page/sub2` | `/_sitemap` | `/about` | `/auth-guard` | `/blog/my-first-post` | `/expo-video` | `/hooks` | `/hooks/contents` | `/hooks/contents/page-1` | `/hooks/contents/page-2` | `/layouts` | `/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]/` | `/loader` | `/loader/other` | `/middleware` | `/not-found/deep/test` | `/not-found/fallback/test` | `/not-found/test` | `/server-data` | `/sheet` | `/spa/spapage` | `/ssr/basic` | `/sub-page` | `/sub-page/sub` | `/sub-page/sub2` | `/web-extensions`
+ DynamicRoutes: `/layouts/nested-layout/with-slug-layout-folder/${OneRouter.SingleRoutePart}` | `/not-found/+not-found` | `/not-found/deep/+not-found` | `/routes/subpath/${string}` | `/spa/${OneRouter.SingleRoutePart}` | `/ssr/${OneRouter.SingleRoutePart}` | `/ssr/${string}`
+ DynamicRouteTemplate: `/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]` | `/not-found/+not-found` | `/not-found/deep/+not-found` | `/routes/subpath/[...subpath]` | `/spa/[spaparams]` | `/ssr/[...rest]` | `/ssr/[param]`
IsTyped: true
}
}
diff --git a/tests/test/tests/layouts.test.ts b/tests/test/tests/layouts.test.ts
new file mode 100644
index 0000000000..0edfd2c5fd
--- /dev/null
+++ b/tests/test/tests/layouts.test.ts
@@ -0,0 +1,41 @@
+import { type Browser, type BrowserContext, chromium } from 'playwright'
+import { afterAll, beforeAll, expect, test, describe } from 'vitest'
+
+const serverUrl = process.env.ONE_SERVER_URL
+const isDebug = !!process.env.DEBUG
+
+let browser: Browser
+let context: BrowserContext
+
+beforeAll(async () => {
+ browser = await chromium.launch({ headless: !isDebug })
+ context = await browser.newContext()
+})
+
+afterAll(async () => {
+ await browser.close()
+})
+
+describe('layouts', async () => {
+ test('nested layout with param', async () => {
+ const page = await context.newPage()
+ await page.goto(serverUrl + '/layouts')
+
+ // This is part of the test - should be able to navigate to the page via link
+ const linkToTestPage = await page.getByTestId('link-to-nested-layout-with-slug-layout-folder')
+ linkToTestPage.click()
+
+ const layoutParamsText = await page.getByTestId('layout-params-json').textContent()
+ const pageParamsText = await page.getByTestId('page-params-json').textContent()
+ const layoutParams = JSON.parse(layoutParamsText || '{}')
+ const pageParams = JSON.parse(pageParamsText || '{}')
+ expect(
+ layoutParams.layoutSlug,
+ 'useParams in _layout should return expected param value for slug on layout directory'
+ ).toBe('someLayoutParam')
+ expect(
+ pageParams.layoutSlug,
+ 'useParams in page should return expected param value for slug on layout directory'
+ ).toBe('someLayoutParam')
+ })
+})