Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@ not working in route paths #2401

Closed
SleepingRobot opened this issue Sep 11, 2021 · 5 comments · Fixed by #2435
Closed

@ not working in route paths #2401

SleepingRobot opened this issue Sep 11, 2021 · 5 comments · Fixed by #2435
Assignees
Milestone

Comments

@SleepingRobot
Copy link

SleepingRobot commented Sep 11, 2021

Describe the bug

Routes containing @ appear to have been broken in @sveltejs/kit 1.0.0-next.163 and result in a 404 error. 162 is working as expected, 163-165 reproduce the issue.

Reproduction

npm init svelte@next
npm install

create file src/routes/@test.svelte with the following contents:

<h1>@test</h1>

run npm run dev

browsing to this url http://localhost:3000/@test displays 404 Not found: /@test error page.

changing @sveltejs/kit from next to 1.0.0-next.162 in package.json, and then running npm i && npm run dev results in the @test page properly loading.

Logs

No response

System Info

System:
    OS: Linux 5.11 Ubuntu 21.04 (Hirsute Hippo)
    CPU: (4) x64 Intel(R) Core(TM) i5-4690K CPU @ 3.50GHz
    Memory: 7.19 GB / 15.47 GB
    Container: Yes
    Shell: 5.1.4 - /bin/bash
  Binaries:
    Node: 16.9.1 - ~/.n/bin/node
    Yarn: 1.22.5 - /usr/bin/yarn
    npm: 7.23.0 - ~/.npm-global/bin/npm
  Browsers:
    Chrome: 93.0.4577.63
    Firefox: 92.0
  npmPackages:
    @sveltejs/kit: next => 1.0.0-next.165 
    svelte: ^3.34.0 => 3.42.5

Severity

serious, but I can work around it

Additional Information

I am using a src/routes/@[username] path in my application for user profile pages, and they are all resulting in 404 errors now. I can technically work around the issue by refactoring my app to use a different user profile path, but I'd really like to avoid that if possible.

@benbender
Copy link

benbender commented Sep 11, 2021

Seeing the same and should be related to #2354. My investigation in dev reveals the following:

route with "@":

page-object:

{
  host: 'localhost:3000',
  path: '/users/@bb',
  query: URLSearchParams {},
  params: {}
}

manifest-entry:

// src/routes/users/@[username]/index.svelte
[/^\/users\/%40([^/]+?)\/?$/, [c[0], c[7]], [c[1]], (m) => ({ username: d(m[1])})],

Note the missing entry in page.params for username and the encoded "@" in the manifest-entry.

Without "@" in the path:

page-object:

{
  host: 'localhost:3000',
  path: '/users/bb',
  query: URLSearchParams {},
  params: { username: 'bb' }
}

manifest-entry:

// src/routes/users/[username]/index.svelte
[/^\/users\/([^/]+?)\/?$/, [c[0], c[7]], [c[1]], (m) => ({ username: d(m[1])})],

If I call "/users/%40bb", it matches the route as expected.

@benmccann benmccann added this to the 1.0 milestone Sep 13, 2021
@benmccann
Copy link
Member

benmccann commented Sep 14, 2021

It looks like the browser does not encode @. However, in #2354 we call encodeURIComponent which does encode it, so they don't match. We could switch to encodeURI, which would fix the issue at least for this character.

I can't figure out how to write a test that fails for @. I suspect that Playwright is handling the URL differently than the browser

@benmccann
Copy link
Member

benmccann commented Sep 14, 2021

Making it work correctly for #, @, and / seems challenging. I think we would have to change the pattern from a single pattern to an array of patterns first splitting on / and then matching against each decoded path segment

@benmccann benmccann self-assigned this Sep 15, 2021
@benmccann
Copy link
Member

benmccann commented Sep 15, 2021

Hmm, splitting first gets super tricky when it comes to spread routes.

Perhaps we should revert #2354, but just require certain characters like /?# to be encoded on the file system as the code did originally. The difficulty will be around making sure that #1746 stays fixed. There's more details about that here: #1746 (comment). If we match against the decoded URL, I'm not exactly sure how to call decodeURIComponent on the parameters without double decoding. Maybe we re-encode first? That seems like not great performance, but for now I just want to get all these cases working and we can optimize later

@benmccann
Copy link
Member

Hmm. That doesn't work.

decodeURIComponent(encodeURI(decodeURI('AC%2fDC'))) returns AC%2fDC while decodeURIComponent('AC%2fDC') returns AC/DC because the first decodeURI leaves the % alone and then it gets encoded again with encodeURI

Maybe what we need to do instead is manually decode the characters that decodeURI doesn't?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants