The goal is to package a server-side rendered Next.js app as SPA for capacitor.
Pages with dynamic routes/data use getServerSideProps(). For capacitor we need at least one page that can be rendered statically, preferably the index page.
When there are pages that use getServerSiedeProps()
we can't use next export
(it will fail with an error).
Instead we use the export.js
script to copy the static pages from /.next/server/pages
to /www
as well as /public
, /.next/static
is copied to /www/_next/static
.
Upon client-side navigation Next.js tries to load the JSON data from /_next/data/${BUILD_ID}/...
. This leads
to a 404 as it resolves to https://localhost
(or capacitor://
) from where capacitor loaded the page.
Unfortunately neither Next's assetPrefix
nor basePath
settings help here.
As workaround we overwrite window.fetch
when the app is served from a capacitor origin and rewrite all URLs
that start with /_next/data
or /_next/api
:
if (typeof window !== "undefined" && (window.origin === "https://localhost" || window.origin === "capacitor://")) {
const _fetch = window.fetch;
window.fetch = (res, init) => {
if (typeof res === "string" && (res.startsWith("/_next/data") || res.startsWith("/_next/api"))) {
res = "http://example.com" + res;
}
return _fetch(res, init);
};
}
The idea is based on James Hegedus' Gist for static asset hoisting for Firebase Hosting CDN: https://gist.github.com/jthegedus/8e820d37e1f3768f991886fb65de154f