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

Getting strange 404 before page loads #2208

Closed
nathanqueija opened this issue Jun 9, 2017 · 43 comments
Closed

Getting strange 404 before page loads #2208

nathanqueija opened this issue Jun 9, 2017 · 43 comments

Comments

@nathanqueija
Copy link

Hi,
I'm getting the 404 error message for 2 seconds and being redirected to the correct page when i try to access any existing route who is handled by custom server.js

Do you know why?

Thanks

@coluccini
Copy link
Contributor

This sounds like an implementation issue. Do you have a repo we can look at?

@burgerzzz
Copy link

+1 - Same issue

@timneutkens
Copy link
Member

Is this in dev mode or production mode? Either way please provide steps to reproduce. Then I'll re-open.

@nathanqueija
Copy link
Author

nathanqueija commented Jul 4, 2017

Hi, I created a gist with my custom server with express that is causing this:

https://gist.github.com/nathanqueija/6273c245f2b46a2417dafa21b7df7692

This happens only if I navigate through Link component, if I go directly to the url it works.

@coluccini
Copy link
Contributor

If you go straight to the url everything renders ok? If yes, it is probably a client side issue. Can we see clients code?

@nathanqueija
Copy link
Author

Yes, it works if I go straight to the url.
Ok...
Here I have a Link component with a button (provided by MaterialUI):
https://gist.github.com/nathanqueija/ddbadc374999298ad9b266ded9352ec8

And, at home page I have this button:

<ButtonWithLink label="Communication" link="/talkwithus/handle/communication" />

This button redirects to "http://localhost:3000/talkwithus/handle/communication" when clicked.

If i go straight to the url it renders normally, but if I click the button to redirect I get the 404 error for 4 seconds then the page is rendered normally.

Why I get this 404 error for 4 or 5 seconds?

@coluccini
Copy link
Contributor

Based on ButtonWithLink code link prop should be only the page you are pointing to talkwithus and the rest should be pass to params as object {operation slug: 'handle', slug: 'communication'}

<ButtonWithLink
  label="Communication"
  link="talkwithus" 
  params={{ operation: 'handle', slug: 'communication' }}
/>

This would take to the url /talkwithus?operation=handle&slug=communication
To take the user to /talkwithus/handle/communication you should add the as props to Link, having something like this:

<ButtonWithLink
  label="Communication"
  link="talkwithus" 
  params={{ operation: 'handle', slug: 'communication' }}
  as="/talkwithus/handle/communication"
/>
export default ({ link, params, as, label }) => (
  <Link href={{ pathname: link || '/', query: params || {} }} as={as}>
    <RaisedButton style={styles.button} label={label} primary />
  </Link>
);

@nathanqueija
Copy link
Author

nathanqueija commented Jul 5, 2017

Hi @coluccini!
But in this case I'll be redirected to the same page that I was: /talkwithus
I'd like to be redirected to another page when I navigate to "/talkwithus/handle/communication", that is why I do this on the server side:

server.get('/talkwithus/:operation/:slug', (req, res) => { return app.render(req, res, '/talkwithus/template', req.params); })

@coluccini
Copy link
Contributor

/talkwithus is the base route or a page? in link you should pass the next.js' page you want to show (by default they are inside /pages) then in params pass the params you need to use inside that page and in as the url you want to show to the client on the url bar.

Can you set up a small repo to look up so I don't need to make that many assumptions?

@nathanqueija
Copy link
Author

/talkwithus is a page

If I go to "/talkwithus/handle/communication" that is not a page I'd like to be redirected to "/talkwithus/template"that is a page.

I'll provide a repo with this piece of code.
Thanks for your attention, man.

@lailo
Copy link

lailo commented Jul 11, 2017

I have the same problem here with 3.0.1-beta.13.

I can load a page /story/123 but when I click a link inside this story to another story /story/987 I get a 404 error.
I use the same link component in other pages and it works, but when I'm already in the story page and want to load another story page, the 404 error appears.

the link looks like this:

<Link
 prefetch
 href={`/story?storyId=${story.id}`}
 as={`/story/${story.id}`}
>
     // more code...
</Link>

Anyone an idea how I could solve this problem?

@fxh615
Copy link

fxh615 commented Sep 1, 2017

i have the problem .

@hesamd
Copy link

hesamd commented Oct 5, 2017

We have the same problem. Our code works flawlessly on next:3.0.3 but we get 404 on 4.0.0-beta.3 and then react loads the page inside 404 (the styling changes). We get 404 regardless of we load the page (link or direct url)

p.s: I realized that my error was trying to access the URL with a trailing slash, React matched it to the page but express complained about it.

@pruhstal
Copy link

pruhstal commented Oct 5, 2017

@lailo-ch @fxh615 in your link component, add the to tag.

So if your real page is /pages/settings/overview.js and in your link you want to send the user to /settings, then do this:

<Link className="link link-underline" href="/settings/overview" to="/settings/overview" as="/settings"></Link>

@obedparla
Copy link
Contributor

Same issue here. Running express 4.16.1 and next "latest".

After debugging for a long while, I noticed that the default route server.get('*', (req, res) => handle(req, res)); will execute even when another route should have priority. For example, if you have a route for /blog/:slug, that route will work, but the server will algo execute the default route.

This causes the app to first go to the literal page /blog/(whatever slug was sent), which ofc doesn't exist, showing a 404 page. After that, the correct route is ran, which will re-render the correct page.

When you go directly to the URL, the correct route runs first, therefore no 404. When you use a Link instead, the default route runs first and then the correct one, hence the 404.

This seems to be a problem with the express integration?? Bug??

Another thing I noticed, I believe the default route is overriding the bundle.js. If I remove the default route, I get the desired behaviour from a module which stores a global variable as per this issue 203. But once I add it back, it always overrides the value on that module in the client-side.

@killinit
Copy link

add / on the end of urls and all will work fine

@obedparla
Copy link
Contributor

For anyone finding this issue in the future. It's not an issue but an incorrect use of the Link routing.

the href of the Link tells the server which Page (as in, the file in your pages folder). The as is just the url the browser will show and push. The href "goes" to the server to fetch the new page. If you're using some weird routing depending on the href to be different than the actual page location, you're gonna get a 404 the first time the server sees it, as it doesn't recognize that page, once the route kicks in and the correct page is rendered, it will show in the browser. But that leaves you with that 404 waiting there until the correct data arrives.

This wasn't clear for me in the documentation for some reason, so there you go.

@timneutkens
Copy link
Member

@obedparla feel free to update the docs 😄

@obedparla
Copy link
Contributor

@timneutkens can you (or someone) confirm what I said is 100% accurate? I'll be happy to make it more readable and make a PR :)

@timneutkens
Copy link
Member

timneutkens commented Nov 5, 2017

Yep, in short:

href is the route to a path inside your pages directory
as is the path pushed to the browser

Example

<Link href="/user/signup" as="/sign-up">

In this case the page pages/user/signup.js is loaded. But the browser will use /sign-up as the url. Do note that wrongfully using the above causes a 404 as you mentioned. Cause this is basically the client side handling of the url. You need to make sure you handle and pass /sign-up to the /user/signup page using a custom server also:

// inspired by https://github.com/zeit/next.js/blob/canary/examples/custom-server/server.js
if (pathname === '/sign-up') {
    app.render(req, res, '/user/signup', query)
}

I guess this is the best description we can give around the issue 😄 🙌

@rayhooker
Copy link

I am not sure I have this right. Like the others I am seeing this problem crop up when I move to 4.1.4 from 3. Also it is not a problem with a "real" 404 that shows up in the browser log but a client side 404, immediately followed by a page load. I have verified in the browser that no 404 shows up in the Network log.

The other issue is that I do have a prefix for my url route of /src. In production this is forwarded from Apache. The backend routes work. The problem is that my configuration is no longer understood by NextJS.

  • The real link that goes to the server and works is:
    /src/school?school=681304&year=2017&lang=english
    The page is school and the example parameters are noted above. I am assuming the page route would be:
    /school?school=681304&year=2017&lang=english

I have tried different combinations of assigning the above to "as=" "href=" but all result under 4.1.4 in a "404" client side followed by a successful retrieval from the server. How do I get it to do the proper client side routing, fetching the page if needed?

Ray

@obedparla
Copy link
Contributor

Hey @rayhooker, can you share your Link? I had the same issue and itwas due to using as and href incorrectly.

@rayhooker
Copy link

rayhooker commented Nov 12, 2017

I have tried:
<Link href={"/school?school=" + this.props.unitcode + "&year=" + this.state.filters.year + "&lang=" + this.props.filters.lang} as={this.props.urlprefix+"/school?school=" + this.props.unitcode + "&year=" + this.state.filters.year + "&lang=" + this.props.filters.lang}>....</Link>

and

<Link as={"/school?school=" + this.props.unitcode + "&year=" + this.state.filters.year + "&lang=" + this.props.filters.lang} href={this.props.urlprefix+"/school?school=" + this.props.unitcode + "&year=" + this.state.filters.year + "&lang=" + this.props.filters.lang}>... </Link>

BTW FWIW the "..." inside the Link is a school address inside an anchor tag that needs to be clickable. Also you can see above what the parameters resolve to as an example:

" school=681304&year=2017&lang=english"

Also note that that I have an assetPrefix in my next.config.js:

module.exports = {
webpack: function (config) {
// config.plugins.push(
// new require('webpack').IgnorePlugin(/ReportListStore/)
// )

return config

},
assetPrefix: process.env.NODE_ENV === 'production' ? '/src/' : ''
// assetPrefix: '/src'
}`

And a url prefix all as per:
https://github.com/zeit/next.js/tree/master/examples/with-universal-configuration

@obedparla
Copy link
Contributor

obedparla commented Nov 13, 2017

I'm pretty sure your issue is caused exactly by what I and Tim explained above @rayhooker.

Your href should be /src/school/whatever. not only /school/whatever. The href is the page in your pages folder, if you ask for a page with an incorrect path the browser won't be able to find it and hence the 404 error. Once the request goes to the server, the server will see what you're requesting, add the prefix, do the routing and whatever else it needs to do, and actually find/serve the page, again, in /src/school.

Try that. If it works please write back here :) I'll do a PR explaining a bit more of this on the docs since it doesn't seem to be clear.

@rayhooker
Copy link

It is not working. Let me explain. The page school is at /src/school and needs the parameters. In the server, node/ express strips the /src and routes it to the proper /page/school. So an example of a full route is:
/src/school?school=920304&year=2017&lang=english

I have tried pointing as to:

  as="/school?school=920304&year=2017&lang=english"

Is the fact that I have parameters (e.g., "school=920304&year=2017&lang=english") causing a problem? Do I need to use object routing to help it understand the pieces?

Ray

@obedparla
Copy link
Contributor

obedparla commented Nov 13, 2017

The parameters are definitely not the problem.

I'm having trouble understanding where your page actually is though, you're kinda contradicting yourself by saying the page is in /src/school but then the server strips the src and redirects to the correct /page/school.

The As is the location of your browser, the error is being caused by the href not finding the page you're requesting, so the browser will show a 404 error until the Link renders a new component a pushes the state.

`Client-side routing behaves exactly like the browser:

The component is fetched
If it defines getInitialProps, data is fetched. If an error occurs, _error.js is rendered
After 1 and 2 complete, pushState is performed and the new component rendered`
https://github.com/zeit/next.js#with-link

I had the exact same problem you're having, my pages needed the info from the route and I was getting a 404, but I fixed it by changing the href to the correct location of the page in my pages folder and leaving the "as" with all the parameters. When that happens your page won't load until the getInitialProps is executed and you've got all your data.

just a quick example, fix it as you see fit.
Link href='/src/school' as="/school?school=920304&year=2017&lang=english" />.

Try that, if that doesn't work I'm at a loss.

@rayhooker
Copy link

Ah finally worked. Actually I needed the parameters on both.

Thanks,
Ray

@lacymorrow
Copy link
Contributor

@obedparla I'm having this issue and starting to pull hair out in frustration. I've followed this thread, I (think I) understand the proper usage of Link, and I'm still getting 404 or Error: Fetch.

To be clear, I'm trying to pass repo names as queries to my index page (main app), I was having issues using server.get('/:repo'...) as it was matching other routes, so I'm trying to have a link like /repo/init-next

My link looks like

// index.js
...
<Link as={`/repo/init-next`} href={`/?repo=init-next`}>

and my (first) server route:

// server.js
		server.get('/repo/:repo', (req, res) => {
		  const actualPage = '/'
		  const queryParams = { repo: req.params.repo } 
		  app.render(req, res, actualPage, queryParams)
		})

@blainegarrett
Copy link

@lacymorrow Are you still having an issue? I just worked through it myself.
It looks pretty much the same as yours. I am on 5.0.1-canary.15

The Link:

<Link as={`/artwork/${id}`} href={`/artwork?artworkId=${id}`}><a className="permalink">{title}</a></Link>

The express server handler

// /server.js
  // Route traffic for /artwork to /page/artwork/index.js
  server.get('/artwork/:artworkId', (req, res) => {
    // url params - note query is ignored. If you need query params AND route params, see: https://github.com/zeit/next.js/blob/master/examples/parameterized-routing/server.js#L25
    return app.render(req, res, '/artwork', req.params);
  });

The page Component:

/pages/artwork/index.js
export default class ArtworkPage extends React.Component {
  static async getInitialProps (ctx) {
    // Get id off query (via <Link as="/artwork?artworkId=..."> and express mapping of params => query)

    let id = ctx.query.artworkId; // Query Params
    // Call REST api
    ...
    }
}

I don't believe this is your issue, but make sure you don't have handlers interfering with next and webpack urls: #1433

@obedparla
Copy link
Contributor

obedparla commented Mar 22, 2018

@lacymorrow you're using the href of Link wrong. Your href is /?repo=init-next but you're expecting '/repo/:repo' in your server's route. It will never catch it since you're not requesting that particular route, you're actually requesting the index page and sending the query repo = init-next.

Try href={/repo/init-next}, that should work fine with the you have. I think you misunderstood how routing works on express. Note that the / at the beginning of the href is also important, if you don't add it, it won't work.

@brothatru
Copy link

brothatru commented Oct 15, 2018

I'm running into a similar issue with a custom route (using the custom express server implementation), except that the page redirect works fine.

Instead, I'm getting a 404 script error, when it tries to load the associated js file with the page that doesn't exist in the /pages folder.

screen shot 2018-10-15 at 4 35 46 pm

Currently using nextjs 6.0.3.

This happens in both dev and prod environments.

Note to see this, you'll have to preserve log in console.

Was wondering if this 404 script error could be avoided?

@wpram
Copy link

wpram commented Oct 27, 2018

I'm running into a similar issue with a custom route (using the custom express server implementation), except that the page redirect works fine.

Instead, I'm getting a 404 script error, when it tries to load the associated js file with the page that doesn't exist in the /pages folder.

screen shot 2018-10-15 at 4 35 46 pm

Currently using nextjs 6.0.3.

This happens in both dev and prod environments.

Note to see this, you'll have to preserve log in console.

Was wondering if this 404 script error could be avoided?

Running into same issue here. I'm not sure what is causing it and how to fix it.

@timneutkens
Copy link
Member

Read this: #2833 (comment)

@huykon
Copy link

huykon commented Feb 28, 2019

I have same problem and still can't resolved it. can anyone help me

@aiwiss
Copy link

aiwiss commented Jun 19, 2019

Had the same issue. I assume this is express and not Next.js (correct me if I'm wrong) but moving route "/comment/:id" above the "*" in server.js solved the issue.

@MarcosRZ
Copy link

After reading the comments It wasn't totally clear for me so here's an example:

<Link href="/post/[slug]" as={`/post/${id}`}>
  <a>{id}</a>
</Link>

Note that href is the exact path of the JS file (without dot and extension as usual).

image

Docs: https://nextjs.org/docs/api-reference/next/link#dynamic-routes

@nlimpag07
Copy link

nlimpag07 commented Jul 12, 2020

I just experience this issue today and for 2 hours it is bugging me.. after reading this thread I rechecked my code and I'm sure all is correct... Then suddenly I noticed my href is href={/courses/[courseId]} as={/courses/${course.id} while my page in Directory is courses/[CourseId].js. Be careful with the naming guys NextJS won't let you escape with mistyping.. hehehe

Be mindful of your declarations. courseId != CourseId != courseID

chubberlisk added a commit to madetech/nhs-virtual-visit that referenced this issue Jul 22, 2020
These would occur because:

- It wasn't known that `pathname` is the route to a path inside `pages` directory,
  not the URL that appears in the browser bar
- When using `Router.push` with dynamic routes e.g.
  `/wards/visits/[id]/edit` you can't pass in `query` so the query parameters has to
  be created manually

Useful links:
- https://nextjs.org/docs/api-reference/next/router#routerpush
- vercel/next.js#2208
- https://stackoverflow.com/questions/316781/how-to-build-query-string-with-javascript
chubberlisk added a commit to madetech/nhs-virtual-visit that referenced this issue Jul 22, 2020
These would occur because:

- It wasn't known that `pathname` is the route to a path inside `pages` directory,
  not the URL that appears in the browser bar
- When using `Router.push` with dynamic routes e.g.
  `/wards/visits/[id]/edit` you can't pass in `query` so the query parameters has to
  be created manually

Useful links:
- https://nextjs.org/docs/api-reference/next/router#routerpush
- vercel/next.js#2208
- https://stackoverflow.com/questions/316781/how-to-build-query-string-with-javascript
chubberlisk added a commit to madetech/nhs-virtual-visit that referenced this issue Jul 22, 2020
These would occur because:

- It wasn't known that `pathname` is the route to a path inside `pages` directory,
  not the URL that appears in the browser bar
- When using `Router.push` with dynamic routes e.g.
  `/wards/visits/[id]/edit` you can't pass in `query` so the query parameters has to
  be created manually

Useful links:
- https://nextjs.org/docs/api-reference/next/router#routerpush
- vercel/next.js#2208
- https://stackoverflow.com/questions/316781/how-to-build-query-string-with-javascript
chubberlisk added a commit to madetech/nhs-virtual-visit that referenced this issue Jul 23, 2020
This is caused by not passing in the correct values for `Router.push`
which needs a `pathname` (path in `pages` directory) and `as` (path
shown in browser URL).

See:
- https://nextjs.org/docs/api-reference/next/router#routerpush
- vercel/next.js#2208
chubberlisk added a commit to madetech/nhs-virtual-visit that referenced this issue Jul 23, 2020
This is caused by not passing in the correct values for `Router.push`
when using dynamic routes which needs a `pathname` (path in `pages` directory)
and `as` (path shown in browser URL).

See:
- https://nextjs.org/docs/api-reference/next/router#routerpush
- vercel/next.js#2208
chubberlisk added a commit to madetech/nhs-virtual-visit that referenced this issue Jul 23, 2020
This is caused by not passing in the correct values for `Router.push`
when using dynamic routes which needs a `pathname` (path in `pages` directory)
and `as` (path shown in browser URL).

See:
- https://nextjs.org/docs/api-reference/next/router#routerpush
- vercel/next.js#2208
@OZZlE
Copy link

OZZlE commented Nov 26, 2020

I updated to latest major version of nextjs 10.0.3 and now things work perfectly fine :) before I got a lot of 404's with 9.4.4

@Wagimo
Copy link

Wagimo commented Nov 10, 2021

Hello, I also have the same problem. my page structure is:
-pages
-product
- [...pid].jsx

The Link that I am using is configured like this:
<Link href = {/product/${product.id}}>
{product.name}

Can you help me identify the error?

Thanks

@RacketyWater7
Copy link

RacketyWater7 commented Dec 2, 2021

None of the above suggestions worked for me either.
Here is my Link component how I'm calling it, yet seeing the same issue.:

<Link
              href="/search"
              as={`${
                isDateRange
                  ? `/search?subject=${paper.subject}&system=${paper.system}&board=${paper.board}&from_date=${paper.from_date}&to_date=${paper.to_date}`
                  : `/search?subject=${paper.subject}&system=${paper.system}&board=${paper.board}&date=${paper.date}`
              }`}
            >
              <a onClick={onSubmit} className="btn-style sign">
                Search
              </a>
            </Link>

and here is the pages folder of my app: Screenshot from 2021-12-02 12-20-46

I'm trying to get to the /search page, and also along with that, I'm adding some values to the query object to use in the next page.
But I'm facing the same issue as others are facing.

Any suggestions would be greatly appreciated!!

@coluccini
Copy link
Contributor

I never used the as property, but I would said you should be using it the other way around

<Link
  as="/search"
  href={
    isDateRange
      ? `/search?subject=${paper.subject}&system=${paper.system}&board=${paper.board}&from_date=${paper.from_date}&to_date=${paper.to_date}`
      : `/search?subject=${paper.subject}&system=${paper.system}&board=${paper.board}&date=${paper.date}`
  }
>

And I don't know what the onSubmit() function does, but I find having 2 nested links with 2 different on click actions (the href on Link and the onClick on the inside <a>) pretty weird.

@RacketyWater7
Copy link

So I did as you prescribed, i.e. I added "/search" in as, and the other long link in href. And I cut the onSubmit function and pasted into the div that is the parent of Link component. And tried it, but it still creates the same error.

P.S. The onSubmit() function is used to validate the search fields and calls the redux toolkit service.

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests