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 || '/'