Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
21 changes: 21 additions & 0 deletions e2e/react-start/custom-basepath/src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { createServerRootRoute } from '@tanstack/react-start/server'
import { Route as rootRouteImport } from './routes/__root'
import { Route as UsersRouteImport } from './routes/users'
import { Route as PostsRouteImport } from './routes/posts'
import { Route as LogoutRouteImport } from './routes/logout'
import { Route as DeferredRouteImport } from './routes/deferred'
import { Route as IndexRouteImport } from './routes/index'
import { Route as UsersIndexRouteImport } from './routes/users.index'
Expand All @@ -35,6 +36,11 @@ const PostsRoute = PostsRouteImport.update({
path: '/posts',
getParentRoute: () => rootRouteImport,
} as any)
const LogoutRoute = LogoutRouteImport.update({
id: '/logout',
path: '/logout',
getParentRoute: () => rootRouteImport,
} as any)
const DeferredRoute = DeferredRouteImport.update({
id: '/deferred',
path: '/deferred',
Expand Down Expand Up @@ -84,6 +90,7 @@ const ApiUsersIdServerRoute = ApiUsersIdServerRouteImport.update({
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/deferred': typeof DeferredRoute
'/logout': typeof LogoutRoute
'/posts': typeof PostsRouteWithChildren
'/users': typeof UsersRouteWithChildren
'/posts/$postId': typeof PostsPostIdRoute
Expand All @@ -95,6 +102,7 @@ export interface FileRoutesByFullPath {
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/deferred': typeof DeferredRoute
'/logout': typeof LogoutRoute
'/posts/$postId': typeof PostsPostIdRoute
'/users/$userId': typeof UsersUserIdRoute
'/posts': typeof PostsIndexRoute
Expand All @@ -105,6 +113,7 @@ export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/deferred': typeof DeferredRoute
'/logout': typeof LogoutRoute
'/posts': typeof PostsRouteWithChildren
'/users': typeof UsersRouteWithChildren
'/posts/$postId': typeof PostsPostIdRoute
Expand All @@ -118,6 +127,7 @@ export interface FileRouteTypes {
fullPaths:
| '/'
| '/deferred'
| '/logout'
| '/posts'
| '/users'
| '/posts/$postId'
Expand All @@ -129,6 +139,7 @@ export interface FileRouteTypes {
to:
| '/'
| '/deferred'
| '/logout'
| '/posts/$postId'
| '/users/$userId'
| '/posts'
Expand All @@ -138,6 +149,7 @@ export interface FileRouteTypes {
| '__root__'
| '/'
| '/deferred'
| '/logout'
| '/posts'
| '/users'
| '/posts/$postId'
Expand All @@ -150,6 +162,7 @@ export interface FileRouteTypes {
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
DeferredRoute: typeof DeferredRoute
LogoutRoute: typeof LogoutRoute
PostsRoute: typeof PostsRouteWithChildren
UsersRoute: typeof UsersRouteWithChildren
PostsPostIdDeepRoute: typeof PostsPostIdDeepRoute
Expand Down Expand Up @@ -195,6 +208,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof PostsRouteImport
parentRoute: typeof rootRouteImport
}
'/logout': {
id: '/logout'
path: '/logout'
fullPath: '/logout'
preLoaderRoute: typeof LogoutRouteImport
parentRoute: typeof rootRouteImport
}
'/deferred': {
id: '/deferred'
path: '/deferred'
Expand Down Expand Up @@ -304,6 +324,7 @@ const ApiUsersServerRouteWithChildren = ApiUsersServerRoute._addFileChildren(
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
DeferredRoute: DeferredRoute,
LogoutRoute: LogoutRoute,
PostsRoute: PostsRouteWithChildren,
UsersRoute: UsersRouteWithChildren,
PostsPostIdDeepRoute: PostsPostIdDeepRoute,
Expand Down
32 changes: 32 additions & 0 deletions e2e/react-start/custom-basepath/src/routes/logout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'

const logoutFn = createServerFn({
method: 'POST',
}).handler(async () => {
// do logout stuff here
throw redirect({
to: '/',
})
})

export const Route = createFileRoute('/logout')({
component: Home,
})

function Home() {
return (
<div className="p-2">
<h3>Logout Page</h3>
<p>
This form tests that server function URLs correctly include the app's
basepath. The form action should be '/custom/basepath/_serverFn/...' not
just '/_serverFn/...'
</p>
<form action={logoutFn.url} method="POST">
<input type="hidden" name="csrfToken" value="123abc" />
<button type="submit">Logout</button>
</form>
</div>
)
}
13 changes: 13 additions & 0 deletions e2e/react-start/custom-basepath/tests/navigation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,16 @@ test('Should change title on client side navigation', async ({ page }) => {

await expect(page).toHaveTitle('Posts page')
})

test('Server function URLs correctly include app basepath', async ({
page,
}) => {
await page.goto('/logout')

const form = page.locator('form')
const actionUrl = await form.getAttribute('action')

expect(actionUrl).toBe(
'/custom/basepath/_serverFn/src_routes_logout_tsx--logoutFn_createServerFn_handler',
)
})
5 changes: 4 additions & 1 deletion packages/start-server-functions-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ export const createServerRpc: CreateRpcFn = (
'🚨splitImportFn required for the server functions server runtime, but was not provided.',
)

const url = `/${sanitizeBase(serverBase)}/${functionId}`
const sanitizedAppBase = sanitizeBase(process.env.TSS_APP_BASE || '/')
const sanitizedServerBase = sanitizeBase(serverBase)

const url = `${sanitizedAppBase ? `/${sanitizedAppBase}` : ``}/${sanitizedServerBase}/${functionId}`

return Object.assign(splitImportFn, {
url,
Expand Down