sveltejs / sveltejs/kit

command() ignores reroute hook — event.route.id reflects un-rerouted path

Open
#15,558 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

router
Dominant language
JavaScript
Stars
20.8k
Forks
2.3k
Avg merge
1d 16h
Merged PRs (30d)
156

Description

Describe the bug

When using SvelteKit's experimental command() (remote functions) from a page that is served via a reroute hook, event.route.id inside the command is null instead of the matched route.

Page navigation correctly resolves event.route.id via the reroute hook. But when a command() is invoked from that same page, event.route.id is null.

Reproduction

Minimal repo: https://github.com/half2me/sveltekit-reroute-command-bug

git clone https://github.com/half2me/sveltekit-reroute-command-bug
cd sveltekit-reroute-command-bug
pnpm install
pnpm dev
  1. Navigate to http://localhost:5173/original
    • The page loads correctly — the reroute hook maps /original/actual
    • In the terminal: [hooks.server] GET /original → route.id: /actual
  2. Click "Call command()"
  3. The page shows event.route.id: nullBUG

Navigate to /actual directly and click the button to verify — in that case event.route.id is correctly /actual.

Setup:

  • src/hooks.ts — reroute hook: /original/actual
  • src/routes/actual/+page.svelte — page with a button calling a command()
  • src/lib/get-route-info.remote.ts — command that returns event.route and event.url
Logs

Page load (correct):

[hooks.server] GET /original → route.id: /actual

Command call (bug):

event.route.id: null
event.url.pathname: /original
Expected behavior

event.route.id should be /actual inside the command(), same as during page navigation.

Actual behavior

event.route.id is null.

Real-world impact

This breaks any handle hook logic that uses event.route.id for command() requests. In our production app we use subdomain-based routing via reroute:

// hooks.ts — reroutes acme.example.com/ → /o/acme
export const reroute: Reroute = ({ url }) => {
  const subdomain = getSubdomain(url.hostname);
  if (subdomain) return `/o/${subdomain}${url.pathname}`;
};
// hooks.server.ts — skips auth for static marketing pages
const handleAuth: Handle = async ({ event, resolve }) => {
  if (event.route.id?.includes('(static)')) return resolve(event);
  // ... set up session ...
};

When a command() is called from acme.example.com/, event.route.id is null instead of /o/[slug]. In our case the un-rerouted / path happened to match a /(static) route group, causing the auth hook to break things.

System Info
SvelteKit 2.55.0
Svelte 5.53.13
Vite 8.0.0
TypeScript 5.9.3
macOS 15.5
Severity

serious, but I can work around it

Additional Information
  • Page loads (GET requests) correctly apply the reroute hook
  • Only command() POST requests are affected
  • The handle hook in hooks.server.ts does run for command requests, but event.route.id is already null by the time it executes

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the linked minimal repository with pnpm install and pnpm dev, then inspect src/hooks.ts, src/routes/actual/+page.svelte, and src/lib/get-route-info.remote.ts. Compare the route information during navigation with the command() POST request and trace where SvelteKit resolves the request route. Done means event.route.id is /actual inside the command when /original is rerouted, while direct /actual behavior remains correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
backend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.