Is it possible to detect reliably if a next.js app is running from server or via next export in getInitialProps and hence client side?
Currently, I am using the presence of res in getIntialProps to find out but I realized that it won't be present for client-side navigation.
I am working on an app and testing the scenario where my backend is down. In an exported site, I should have all the data available already but my JS code calls backend in getInitialProps and crashes.
In the place where I am catching this error, I can trigger a location.reload() to render the content statically and serve users without the backend being up.
This is one of a few use cases.
| Tech | Version |
|---------|---------|
| next | v4.2.3 |
| node | v8.4.0 |
| OS | MacOS high sierra 10.13.3 |
| browser | 63.0.3239.132 |
| etc | |
This is different from https://github.com/zeit/next.js/issues/1229 because I want to run a piece of code only when the site is exported and just detecting client side won't solve my use case.
I think that what I am proposing is a workaround and the better solution would be that the links turn to normal <a href="<static link>"> links on next export
Here's the code I use:
static async getInitialProps({ req }) {
const isServer = typeof window === 'undefined'
if (isServer && !req.headers) {
// Inside static export
return {}
}
return {}
}
But we should add a better way.
How about
I think that what I am proposing is a workaround and the better solution would be that the links turn to normal
<a href="<static link>">links onnext export
Is it possible to turn all <Link> components to normal <a> tag on static export?
Should I raise a separate issue for it?
Thanks!
Adding a similar issue(s) for reference:
Also, the above snippet does not solve it for me. While on direct access to a link I get exported as true but while navigating within the site - using next/link, I get that value as false.
My requirement is to be able to detect the exported state correctly for both direct access and navigation within the site.
Here is how I am using it inside getInitialProps
let exported = false;
const isServer = typeof window === "undefined";
if (isServer && !req.headers) {
// Inside static export
exported = true;
}
@divyenduz we handle Links differently in the static mode. So, simply changing it back to <a/> loose the SPA nature of the app.
But if you like to do it, create a custom Link component which return <a/> in static export mode.
For that, you may need to invoke an env variable to detect the next-export until we provide an API for that.
Noted. Thanks for the response.
My query on this issue is resolved but I will keep it open until the export detection API is there.
Please let me know if I should close it now. Thanks.
@divyenduz let's keep this open.
Hi, are there any updates on the export detection API?
For the record, if you want to adopt specific behaviors during the export phase AND on the client, you can add a static getInitialProps method to you pages components and do it this way :
const isExported = ctx => {
const isServer = typeof window === "undefined"
return (
(isServer && ctx.req.headers === undefined) ||
(!isServer && window.__NEXT_DATA__.nextExport)
);
};
Page.getInitialProps = ctx => {
return { isExported: isExported(ctx) }
}
You can then use the new isExported prop in your page component tree and use in conditions wherever you want ;)
@timneutkens : Is it a future proof way of doing it ?
Closing this in favor of another RFC we're working on.
Is @arunoda's technique above still the recommended way to do this? What was the other RFC @timneutkens was referring to?
Most helpful comment
Here's the code I use:
But we should add a better way.