diff --git a/e2e/react-router/basic-file-based/src/routeTree.gen.ts b/e2e/react-router/basic-file-based/src/routeTree.gen.ts index 4efc03e2827..8150c3354d4 100644 --- a/e2e/react-router/basic-file-based/src/routeTree.gen.ts +++ b/e2e/react-router/basic-file-based/src/routeTree.gen.ts @@ -11,6 +11,7 @@ import { createFileRoute } from '@tanstack/react-router' import { Route as rootRouteImport } from './routes/__root' +import { Route as Char45824Char54620Char48124Char44397RouteImport } from './routes/대한민국' import { Route as PostsRouteImport } from './routes/posts' import { Route as EditingBRouteImport } from './routes/editing-b' import { Route as EditingARouteImport } from './routes/editing-a' @@ -58,6 +59,12 @@ const groupRoute = groupRouteImport.update({ id: '/(group)', getParentRoute: () => rootRouteImport, } as any) +const Char45824Char54620Char48124Char44397Route = + Char45824Char54620Char48124Char44397RouteImport.update({ + id: '/대한민국', + path: '/대한민국', + getParentRoute: () => rootRouteImport, + } as any) const PostsRoute = PostsRouteImport.update({ id: '/posts', path: '/posts', @@ -272,6 +279,7 @@ export interface FileRoutesByFullPath { '/editing-a': typeof EditingARoute '/editing-b': typeof EditingBRoute '/posts': typeof PostsRouteWithChildren + '/대한민국': typeof Char45824Char54620Char48124Char44397Route '/onlyrouteinside': typeof anotherGroupOnlyrouteinsideRoute '/inside': typeof groupInsideRoute '/lazyinside': typeof groupLazyinsideRoute @@ -309,6 +317,7 @@ export interface FileRoutesByTo { '/anchor': typeof AnchorRoute '/editing-a': typeof EditingARoute '/editing-b': typeof EditingBRoute + '/대한민국': typeof Char45824Char54620Char48124Char44397Route '/onlyrouteinside': typeof anotherGroupOnlyrouteinsideRoute '/inside': typeof groupInsideRoute '/lazyinside': typeof groupLazyinsideRoute @@ -349,6 +358,7 @@ export interface FileRoutesById { '/editing-a': typeof EditingARoute '/editing-b': typeof EditingBRoute '/posts': typeof PostsRouteWithChildren + '/대한민국': typeof Char45824Char54620Char48124Char44397Route '/(another-group)/onlyrouteinside': typeof anotherGroupOnlyrouteinsideRoute '/(group)': typeof groupRouteWithChildren '/(group)/_layout': typeof groupLayoutRouteWithChildren @@ -393,6 +403,7 @@ export interface FileRouteTypes { | '/editing-a' | '/editing-b' | '/posts' + | '/대한민국' | '/onlyrouteinside' | '/inside' | '/lazyinside' @@ -430,6 +441,7 @@ export interface FileRouteTypes { | '/anchor' | '/editing-a' | '/editing-b' + | '/대한민국' | '/onlyrouteinside' | '/inside' | '/lazyinside' @@ -469,6 +481,7 @@ export interface FileRouteTypes { | '/editing-a' | '/editing-b' | '/posts' + | '/대한민국' | '/(another-group)/onlyrouteinside' | '/(group)' | '/(group)/_layout' @@ -513,6 +526,7 @@ export interface RootRouteChildren { EditingARoute: typeof EditingARoute EditingBRoute: typeof EditingBRoute PostsRoute: typeof PostsRouteWithChildren + Char45824Char54620Char48124Char44397Route: typeof Char45824Char54620Char48124Char44397Route anotherGroupOnlyrouteinsideRoute: typeof anotherGroupOnlyrouteinsideRoute groupRoute: typeof groupRouteWithChildren RedirectTargetRoute: typeof RedirectTargetRouteWithChildren @@ -543,6 +557,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof groupRouteImport parentRoute: typeof rootRouteImport } + '/대한민국': { + id: '/대한민국' + path: '/대한민국' + fullPath: '/대한민국' + preLoaderRoute: typeof Char45824Char54620Char48124Char44397RouteImport + parentRoute: typeof rootRouteImport + } '/posts': { id: '/posts' path: '/posts' @@ -928,6 +949,8 @@ const rootRouteChildren: RootRouteChildren = { EditingARoute: EditingARoute, EditingBRoute: EditingBRoute, PostsRoute: PostsRouteWithChildren, + Char45824Char54620Char48124Char44397Route: + Char45824Char54620Char48124Char44397Route, anotherGroupOnlyrouteinsideRoute: anotherGroupOnlyrouteinsideRoute, groupRoute: groupRouteWithChildren, RedirectTargetRoute: RedirectTargetRouteWithChildren, diff --git "a/e2e/react-router/basic-file-based/src/routes/\353\214\200\355\225\234\353\257\274\352\265\255.tsx" "b/e2e/react-router/basic-file-based/src/routes/\353\214\200\355\225\234\353\257\274\352\265\255.tsx" new file mode 100644 index 00000000000..c70cb5096a9 --- /dev/null +++ "b/e2e/react-router/basic-file-based/src/routes/\353\214\200\355\225\234\353\257\274\352\265\255.tsx" @@ -0,0 +1,9 @@ +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/대한민국')({ + component: RouteComponent, +}) + +function RouteComponent() { + return
Hello "/대한민국"!
+} diff --git a/e2e/react-router/basic-file-based/tests/params.spec.ts b/e2e/react-router/basic-file-based/tests/params.spec.ts index 5d4c6111b78..546fa80d31e 100644 --- a/e2e/react-router/basic-file-based/tests/params.spec.ts +++ b/e2e/react-router/basic-file-based/tests/params.spec.ts @@ -202,3 +202,13 @@ test.describe('params operations + prefix/suffix', () => { }) }) }) + +test.describe('Unicode route rendering', () => { + test('should render non-latin route correctly', async ({ page, baseURL }) => { + await page.goto('/대한민국') + + await expect(page.locator('body')).toContainText('Hello "/대한민국"!') + + expect(page.url()).toBe(`${baseURL}/%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD`) + }) +}) diff --git a/e2e/react-start/basic/src/routeTree.gen.ts b/e2e/react-start/basic/src/routeTree.gen.ts index 1eaa3c34e22..b6fc9282f67 100644 --- a/e2e/react-start/basic/src/routeTree.gen.ts +++ b/e2e/react-start/basic/src/routeTree.gen.ts @@ -17,6 +17,7 @@ import type { import { createServerRootRoute } from '@tanstack/react-start/server' import { Route as rootRouteImport } from './routes/__root' +import { Route as Char45824Char54620Char48124Char44397RouteImport } from './routes/대한민국' import { Route as UsersRouteImport } from './routes/users' import { Route as StreamRouteImport } from './routes/stream' import { Route as ScriptsRouteImport } from './routes/scripts' @@ -58,6 +59,12 @@ import { ServerRoute as ApiUsersIdServerRouteImport } from './routes/api/users.$ const FooBarQuxRouteImport = createFileRoute('/foo/$bar/$qux')() const rootServerRouteImport = createServerRootRoute() +const Char45824Char54620Char48124Char44397Route = + Char45824Char54620Char48124Char44397RouteImport.update({ + id: '/대한민국', + path: '/대한민국', + getParentRoute: () => rootRouteImport, + } as any) const UsersRoute = UsersRouteImport.update({ id: '/users', path: '/users', @@ -262,6 +269,7 @@ export interface FileRoutesByFullPath { '/scripts': typeof ScriptsRoute '/stream': typeof StreamRoute '/users': typeof UsersRouteWithChildren + '/대한민국': typeof Char45824Char54620Char48124Char44397Route '/not-found/via-beforeLoad': typeof NotFoundViaBeforeLoadRoute '/not-found/via-loader': typeof NotFoundViaLoaderRoute '/posts/$postId': typeof PostsPostIdRoute @@ -293,6 +301,7 @@ export interface FileRoutesByTo { '/links': typeof LinksRoute '/scripts': typeof ScriptsRoute '/stream': typeof StreamRoute + '/대한민국': typeof Char45824Char54620Char48124Char44397Route '/not-found/via-beforeLoad': typeof NotFoundViaBeforeLoadRoute '/not-found/via-loader': typeof NotFoundViaLoaderRoute '/posts/$postId': typeof PostsPostIdRoute @@ -328,6 +337,7 @@ export interface FileRoutesById { '/scripts': typeof ScriptsRoute '/stream': typeof StreamRoute '/users': typeof UsersRouteWithChildren + '/대한민국': typeof Char45824Char54620Char48124Char44397Route '/_layout/_layout-2': typeof LayoutLayout2RouteWithChildren '/not-found/via-beforeLoad': typeof NotFoundViaBeforeLoadRoute '/not-found/via-loader': typeof NotFoundViaLoaderRoute @@ -367,6 +377,7 @@ export interface FileRouteTypes { | '/scripts' | '/stream' | '/users' + | '/대한민국' | '/not-found/via-beforeLoad' | '/not-found/via-loader' | '/posts/$postId' @@ -398,6 +409,7 @@ export interface FileRouteTypes { | '/links' | '/scripts' | '/stream' + | '/대한민국' | '/not-found/via-beforeLoad' | '/not-found/via-loader' | '/posts/$postId' @@ -432,6 +444,7 @@ export interface FileRouteTypes { | '/scripts' | '/stream' | '/users' + | '/대한민국' | '/_layout/_layout-2' | '/not-found/via-beforeLoad' | '/not-found/via-loader' @@ -471,6 +484,7 @@ export interface RootRouteChildren { ScriptsRoute: typeof ScriptsRoute StreamRoute: typeof StreamRoute UsersRoute: typeof UsersRouteWithChildren + Char45824Char54620Char48124Char44397Route: typeof Char45824Char54620Char48124Char44397Route RedirectTargetRoute: typeof RedirectTargetRouteWithChildren RedirectIndexRoute: typeof RedirectIndexRoute PostsPostIdDeepRoute: typeof PostsPostIdDeepRoute @@ -573,6 +587,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof UsersRouteImport parentRoute: typeof rootRouteImport } + '/대한민국': { + id: '/대한민국' + path: '/대한민국' + fullPath: '/대한민국' + preLoaderRoute: typeof Char45824Char54620Char48124Char44397RouteImport + parentRoute: typeof rootRouteImport + } '/_layout/_layout-2': { id: '/_layout/_layout-2' path: '' @@ -843,6 +864,13 @@ declare module '@tanstack/react-start/server' { preLoaderRoute: unknown parentRoute: typeof rootServerRouteImport } + '/대한민국': { + id: '/대한민국' + path: '/대한민국' + fullPath: '/대한민국' + preLoaderRoute: unknown + parentRoute: typeof rootServerRouteImport + } '/_layout/_layout-2': { id: '/_layout/_layout-2' path: '' @@ -1205,6 +1233,23 @@ declare module './routes/users' { unknown > } +declare module './routes/대한민국' { + const createFileRoute: CreateFileRoute< + '/대한민국', + FileRoutesByPath['/대한민국']['parentRoute'], + FileRoutesByPath['/대한민국']['id'], + FileRoutesByPath['/대한민국']['path'], + FileRoutesByPath['/대한민국']['fullPath'] + > + + const createServerFileRoute: CreateServerFileRoute< + ServerFileRoutesByPath['/대한민국']['parentRoute'], + ServerFileRoutesByPath['/대한민국']['id'], + ServerFileRoutesByPath['/대한민국']['path'], + ServerFileRoutesByPath['/대한민국']['fullPath'], + unknown + > +} declare module './routes/_layout/_layout-2' { const createFileRoute: CreateFileRoute< '/_layout/_layout-2', @@ -1818,6 +1863,8 @@ const rootRouteChildren: RootRouteChildren = { ScriptsRoute: ScriptsRoute, StreamRoute: StreamRoute, UsersRoute: UsersRouteWithChildren, + Char45824Char54620Char48124Char44397Route: + Char45824Char54620Char48124Char44397Route, RedirectTargetRoute: RedirectTargetRouteWithChildren, RedirectIndexRoute: RedirectIndexRoute, PostsPostIdDeepRoute: PostsPostIdDeepRoute, diff --git "a/e2e/react-start/basic/src/routes/\353\214\200\355\225\234\353\257\274\352\265\255.tsx" "b/e2e/react-start/basic/src/routes/\353\214\200\355\225\234\353\257\274\352\265\255.tsx" new file mode 100644 index 00000000000..99448326772 --- /dev/null +++ "b/e2e/react-start/basic/src/routes/\353\214\200\355\225\234\353\257\274\352\265\255.tsx" @@ -0,0 +1,7 @@ +export const Route = createFileRoute({ + component: RouteComponent, +}) + +function RouteComponent() { + return
Hello "/대한민국"!
+} diff --git a/e2e/react-start/basic/tests/params.spec.ts b/e2e/react-start/basic/tests/params.spec.ts new file mode 100644 index 00000000000..b22c3e26554 --- /dev/null +++ b/e2e/react-start/basic/tests/params.spec.ts @@ -0,0 +1,15 @@ +import { expect, test } from '@playwright/test' + +test.beforeEach(async ({ page }) => { + await page.goto('/') +}) + +test.describe('Unicode route rendering', () => { + test('should render non-latin route correctly', async ({ page, baseURL }) => { + await page.goto('/대한민국') + + await expect(page.locator('body')).toContainText('Hello "/대한민국"!') + + expect(page.url()).toBe(`${baseURL}/%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD`) + }) +}) diff --git a/packages/start-server-core/src/createStartHandler.ts b/packages/start-server-core/src/createStartHandler.ts index dcfe9e7d4f8..0321412f924 100644 --- a/packages/start-server-core/src/createStartHandler.ts +++ b/packages/start-server-core/src/createStartHandler.ts @@ -110,7 +110,7 @@ export function createStartHandler({ } const url = new URL(request.url) - const href = url.href.replace(url.origin, '') + const href = decodeURIComponent(url.href.replace(url.origin, '')) const APP_BASE = process.env.TSS_APP_BASE || '/'