Skip to content
This repository has been archived by the owner on May 10, 2021. It is now read-only.

Page chunk for catch-all page at root level is evaluated/rendered on the server #43

Closed
Yegair opened this issue Sep 30, 2020 · 8 comments · Fixed by #52
Closed

Page chunk for catch-all page at root level is evaluated/rendered on the server #43

Yegair opened this issue Sep 30, 2020 · 8 comments · Fixed by #52

Comments

@Yegair
Copy link

Yegair commented Sep 30, 2020

Hello,

First of all thanks for the great work with next-on-netlify, highly appreciated!


What is wrong?

If have a custom app which makes use of SSR via getInitialProps.

pages/_app.jsx:

import React from 'react';
import App from 'next/app';

const MyApp = ({ Component, pageProps, ...customProps }) => {
    return <Component {...pageProps} {...customProps} />;
};

// having a custom app with getInitialProps forces all pages to be rendered on the server
MyApp.getInitialProps = async (ctx) => {
    const appProps = App.getInitialProps(ctx);
    return {
        ...appProps,
        somePropFrom_app: "Hello from the _app"
    };
};

export default MyApp;

Also I have a catch-all page which is used as the index page and as a fallback if there is no matching page for the current route (obviously).

pages/[[...any]].jsx:

import React, { useEffect, useState } from 'react';

export default ({ somePropFrom_app }) => {
    const [ someState, setSomeState ] = useState('waiting for client side code execution...');

    useEffect(() => {
        setSomeState('client side code was executed properly!')
    });

    return (
        <main>
            <p>{somePropFrom_app}</p>
            <p>{someState}</p>
        </main>
    )
}

When I access the catch-all page it is being rendered on the server correctly, but the client side rendering fails. It seems the server sends the rendered HTML instead of the JS source code when the frontend fetches the static JS chunk for this page.

console

When I look at the network tab, I can see that the browser tried to fetch the JS chunk, but received fully rendered HTML instead:

network

As far as I could test it, this seems not to happen for catch-all pages within subdirectories. For example
pages/foo/[[...any]].jsx works as expected.

How to reproduce?

I have set up a minimal repository which reproduces the issue: https://github.com/Yegair/next-on-netlify-minimal.
You can also have a look at the running example here: https://condescending-allen-4992da.netlify.app/

Are there related issues?

This issue may be related to #41 (at least the workaround is the same).

Is there a Workaround?

As I said above, the Workaround from #41 seems to resolve the issue.
Just add a "No-Op redirect" for the /_next/* route:

_redirects:

/_next/* /_next/:splat 200
@FinnWoelm
Copy link
Collaborator

Hi @Yegair,

Thank you for your kind words and for this detailed issue report! I think you are absolutely right — it's probably related to issue #41.

@lindsaylevine is already in touch with the team that manages the Netlify redirects/rewrites feature, to see if they can dig into the issue. We will keep you and everyone else posted here!

For now, it's best to use the "no-op redirect" you mentioned.

Stay tuned and thanks again for the report & repo to reproduce the issue! 🔥

@mraerino
Copy link
Member

mraerino commented Oct 5, 2020

@FinnWoelm i'm curious: why wouldn't you add that /_next/* /_next/:splat 200 rule to the redirects file in the build process of next-on-netlify?
it seems to always be a good idea right?

@FinnWoelm
Copy link
Collaborator

Hi @mraerino, thanks for checking this out! Really appreciate your help!

All redirects generated by next-on-netlify are non-force redirects, so they should not shadow existing files. This always works correctly, except in the case where the asset has a square bracket in its filename. Then the URL gets shadowed even though a local file exists!

In fact, the URL only gets shadowed/rewritten when the square brackets are URI encoded: https://example.com/%5B%5B...any%5D%5D.js. On the other hand, the request for https://example.com/[[...any]].js works totally fine. So that led us to suspect that perhaps the netlify.app logic for checking if a local file exists may not correctly decode URIs.

Adding to that suspicion is the fact that this issue only occurs when a catch-all redirect is present, such as: /* /myfile.html 200. Without that redirect, the URL with encoded square brackets yields the correct file. With that redirect, the same URL with encoded square brackets incorrectly gets rewritten to myfile.html.

Please correct me if I'm wrong, but doesn't the fact, that a redirect with /_next/* /_next/:splat 200 solves this issue, further add to the suggestion that there is an issue with decoding the URI? The redirect should not be necessary thanks to Netlify's shadowing rules (unless, of course, we had some forced redirects in our _redirects file, but there aren't any).

We wanted to raise this issue (rather than locally fix it with /_next/* /_next/:splat 200), in case there is actually an issue with the shadowing logic. Because if so, it might affect others using SPA with catch-all redirects (.e.g., a React app with /* /index.html 200) and local files with square brackets in their names (admittedly, it's not super common to have these in your file names).

Does that make sense? Am I mistaken in my understanding of how things should work? Happy to chat more at any time, if it would be helpful!

@mraerino
Copy link
Member

mraerino commented Oct 5, 2020

In fact, the URL only gets shadowed/rewritten when the square brackets are URI encoded: https://example.com/%5B%5B...any%5D%5D.js. On the other hand, the request for https://example.com/[[...any]].js works totally fine. So that led us to suspect that perhaps the netlify.app logic for checking if a local file exists may not correctly decode URIs.

thank you for pointing out that detail. seems to be something we'd want to fix in the future. i'll make sure to open an internal issue.

would there be a way to publish that file without special characters for now?

@FinnWoelm
Copy link
Collaborator

Hey @mraerino, that's awesome to hear!! 🙌 😊

We can't publish it without special characters (it's created that way by the framework and there are a lot of internal references to those files with square brackets), but I think we will do the /_next/* /_next/:splat 200 thing as you have suggested!

Thank you again for looking into this :)

@afzalsayed96
Copy link
Contributor

Hi @FinnWoelm,

I'm facing this issue when I have something like pages/index.js & pages/[...rest].js.

The temporary /_next/* /_next/:splat 200 fix does not get applied in this case as it is not considered root level catch-all route.

The redirects generated are

/:rest/*  /.netlify/functions/next_rest  200

@lindsaylevine
Copy link
Contributor

@afzalsayed96 looking into this, thanks for reporting!

@lindsaylevine
Copy link
Contributor

#77 re-addresses this :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
5 participants