This might be built in (if it's not too opinionated), or a separate "core module" (if it has too many "options").
The idea is that one will be able to run next export
and yield a build
directory that _doesn't require a server_.
next export -o customDir
should be possiblegetInitialProps
to have pre-rendered data when it's first loadednext.config.js
(export
object)How about if we ignore getInitialProps
for the static build.
We simply ignore that.
Is that something we could consider?
Definitely. Client-only getInitialProps
is a possibility.
@rauchg @arunoda Wouldn't ignoring getInitialProps
defeat the purpose of a static site? There would still be a need for a server to get those initial props right? Or did I maybe miss something in the previous discussion?
There are two forms of static sites. The one where the data is 100% static, and the one where it's not. And there's a hybrid where you ship props pre-computed with each page and data can still be fetched dynamically
@rauchg React inherently allows the hybrid form trough its componendDidMount
hook. I'd love to see the next export
feature to generate a truly static site, otherwise I'll have to open another feature request once it is finished ;)
There are two forms of static sites. The one where the data is 100% static, and the one where it's not. And there's a hybrid where you ship props pre-computed with each page and data can still be fetched dynamically
What type of static site is this command planning on exporting?
Let's perhaps define them these ways:
Also, what exactly is the benefit of zeit:next exporting a static site?
@balupton Allows one to host on github pages, aws s3, etc.
As an alternative, I tried to get the static content using wget. Although it works with other of my projects (without using next), it does not work well here with next.
@jferrettiboke @stretchkennedy Where internal links are unknown at "build time", I think the approach used by static-site-generator-webpack-plugin where you simply list all of the URLs it needs to render in one place, works quite well.
Of course you don't want to be doing this by hand - I have a script that does this based on matching file names within a directory: find-posts
( Continuing conversation here from #604 )
@balupton Allows one to host on github pages, aws s3, etc.
But the only reason I can imagine of why people want to deploy to them is because they are free and quick hosting -however zeit:now + cloudflare accomplishes the same - with much more coolness
@balupton Not really, if you have a static site which does not have to render the app or fetch data on the backend before it is sent to the server you can gain a lot of speed. This is the main reason I make static web-apps.
@yn5 I think he's talking about using cloudflare's caching.
For myself, the reason I want to render a static site is to lower the attack surface and to consume fewer resources. Deploying nodejs requires keeping more dependencies up to date than just deploying nginx, and wastes a perfectly good VM even if you put it behind cloudflare.
@balupton But the only reason I can imagine of why people want to deploy to them is because they are free and quick hosting -however zeit:now + cloudflare accomplishes the same - with much more coolness
I agree with the reasons mentioned by @stretchkennedy and @yn5 - but I'll also add that the over-arching goal should be to move towards being more permissive; rather than to restrict the options. If a particular site is truly static in nature, then why preclude having the option of being able to serve from a static host?
Additionally, enabling zeit to work with a flow that one has already invested time in setting up and tweaking (e.g. in your CI/ CD pipeline), rather than having to set up a new flow, is a win.
I'd like to toss in my hat on how I think this could work really well:
static getInitialProps ({ build, req }) {
if (req) {
// server-side
} else if (build) {
// static build (can contains parameters about the page build)
// this happens at the time of the build (next export)
} else {
// client-side
}
}
next export
will generate HTML & JSON representations of each top-level page component.
<Link href="...">
The cool thing about this is that you can pull in markdown files and other resources (even pre-render a page) all from within that build == true
condition.
@matthewmueller would it be possible to eliminate code from getInitialProps()
on build?
Let's say you use an API to fetch live data during development and you want to "bake" it into a static build (both in the HTML and JSON representation of a page), to eliminate any API requests in production. This would be awesome for a collaborative workflow.
To optimize the output you'd probably then remove the dependency on whatever API library you use to fetch data in getInitialProps()
during dev/build time because you can basically just replace it with the API response.
static async getInitialProps ({ build, req }) {
if (build) {
return myCoolAPILib.fetch('foobar.csv') // Probably load myCoolAPILib through webpack's async import()?
}
}
gets turned into:
static async getInitialProps () {
return {
// Response from myCoolAPILib
};
}
So how would you handle code splitting? Right now, for dynamically rendered pages, Next requests a JSON file with the components. Would these be statically published as well?
@kbingman yep, i believe the json versions are built and written to the filesystem anyway.
From a dev-ops, scaling, speed and pricing point of view, nothing beats a static page on S3. So this feature is actually super important for us.
@kbingman those will be statically generated indeed as well
Is anyone actively working on this yet? If not, I might give it a shot since I'm very interested in this feature.
I did some spelunking in the next.js codebase and got an extremely rough proof-of-concept working by basically adding another step to the build using the server's renderToHTML
function.
As far as I can tell it's pretty straight-forward. One of the bigger challenges will be to deal with dynamic routes like /posts/:id
, especially if they're not referenced by links in the HTML (which would make them un-crawlable). So probably the user should be able to provide a static list of routes.
@herrstucki
One of the bigger challenges will be to deal with dynamic routes like /posts/:id, especially if they're not referenced by links in the HTML
Thats what I'm looking for. I hope to find a way to generate pages from markdown-files, and list them in a dynamic-navigation.
@schoenwaldnils
I agree with this. Would be awesome to have a react-powered Jekyll replacement. (I realize much of that blog functionality is out of scope). But this definitely would make next.js a solid platform for a larger audience who might want to throw things on gh-pages or S3.
@kylehotchkiss Absolutely! This is exactly what I currently have in mind.
The main problem in my case(s) is, that the site still should be maintainable by the marketing-team through cloudcannon, prose.io or something like that.
And I think markdown with configurable meta is still the best way to add easy content-editing.
@herrstucki I'm working on this a bit, happy to collaborate on a branch. definitely need this feature as well. I think this can be done entirely via the plugin system, then we can make it nicer / a bit more native later.
@schoenwaldnils you could achieve that sort of functionality by passing a { build: true }
or any other indicator during the static build step to getInitialProps()
.
Regarding routing, at least for an initial implementation, I think only the development server needs to be route-aware, which you can achieved with a custom server. When you export to static, a service like Cloudfront or netlify can take the routing from there and you can use <Link href="/post" as="/post/4">...</Link>
to do the dynamic stuff.
PR has landed: https://github.com/zeit/next.js/pull/1576 馃挜
Now we've "next export" support built into the core.
See: https://zeit.co/blog/next3-preview
Thanks everyone for all the help.
Great to see this happend. Amazing work guys!
Hi, next export
generates a subfolder called _next
, is there any way to automatically rename it?
@arunoda
How do you guys handle DOM events with next export
? Thx!
[EDIT] on Mac I need to manually change all src="/_next/xxxx"
paths to src="./_next/xxxx"
@arunoda
@juliandavidmr @sbe88
You need to set the assetPrefix
variable in the next.config.js
file.
you can also look through these for better explanation.
https://medium.com/@anotherplanet/git-tips-next-js-github-pages-2dbc9a819cb8
https://medium.com/@adibas03/next-js-github-pages-contd-42a1dd47f6bc
Most helpful comment
PR has landed: https://github.com/zeit/next.js/pull/1576 馃挜