From 130c5bce6768c2aff2028c910290a1cfbb77135c Mon Sep 17 00:00:00 2001 From: Finn Woelm Date: Thu, 16 Jul 2020 07:27:44 +0200 Subject: [PATCH 1/3] Add examples for GIP, GSSP, GSP, API, and preview mode Completely rewrite the demo page, showcasing the features of next-on-netlify v2: basic and dynamic routing for getInitialProps, getServerSideProps, getStaticProps, API endpoints, and preview mode. --- package-lock.json | 6 + package.json | 3 + pages/api/[...slug].js | 41 +++++ pages/api/[id].js | 38 ++++ pages/api/enterPreview/[id].js | 12 ++ pages/api/exitPreview/[id].js | 13 ++ pages/api/image.js | 10 ++ pages/api/redirect.js | 4 + pages/api/show.js | 11 ++ pages/api/xml.js | 13 ++ pages/getInitialProps/[...slug].js | 82 +++++++++ pages/getInitialProps/[id].js | 69 +++++++ pages/getInitialProps/show.js | 54 ++++++ pages/getServerSideProps/[...slug].js | 81 +++++++++ pages/getServerSideProps/[id].js | 68 +++++++ pages/getServerSideProps/show.js | 58 ++++++ pages/getStaticProps/[...slug].js | 109 ++++++++++++ pages/getStaticProps/[id].js | 71 ++++++++ pages/getStaticProps/show.js | 57 ++++++ pages/getStaticProps/withFallback/[id].js | 96 ++++++++++ pages/index.js | 208 +++++++++++++--------- pages/previewMode/[id].js | 122 +++++++++++++ pages/shows/[...params].js | 64 ------- pages/shows/[id].js | 53 ------ pages/static.js | 27 --- pages/static/[id].js | 33 ---- pages/you-have-been-redirected.js | 30 ++++ roll.jpg | Bin 0 -> 47668 bytes 28 files changed, 1176 insertions(+), 257 deletions(-) create mode 100644 pages/api/[...slug].js create mode 100644 pages/api/[id].js create mode 100644 pages/api/enterPreview/[id].js create mode 100644 pages/api/exitPreview/[id].js create mode 100644 pages/api/image.js create mode 100644 pages/api/redirect.js create mode 100644 pages/api/show.js create mode 100644 pages/api/xml.js create mode 100644 pages/getInitialProps/[...slug].js create mode 100644 pages/getInitialProps/[id].js create mode 100644 pages/getInitialProps/show.js create mode 100644 pages/getServerSideProps/[...slug].js create mode 100644 pages/getServerSideProps/[id].js create mode 100644 pages/getServerSideProps/show.js create mode 100644 pages/getStaticProps/[...slug].js create mode 100644 pages/getStaticProps/[id].js create mode 100644 pages/getStaticProps/show.js create mode 100644 pages/getStaticProps/withFallback/[id].js create mode 100644 pages/previewMode/[id].js delete mode 100644 pages/shows/[...params].js delete mode 100644 pages/shows/[id].js delete mode 100644 pages/static.js delete mode 100644 pages/static/[id].js create mode 100644 pages/you-have-been-redirected.js create mode 100644 roll.jpg diff --git a/package-lock.json b/package-lock.json index 29c75a3..631aeda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2246,6 +2246,12 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "buffer-loader": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/buffer-loader/-/buffer-loader-0.1.0.tgz", + "integrity": "sha512-ucbiQL7IicJm1EHuXC4Oheu2oGjz6qKRmyqAXYTtWe4iC49743AU2DHlWpF51qKF+g/t62Jk8Yn+3FaCz5jJEA==", + "dev": true + }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", diff --git a/package.json b/package.json index 5941b60..7ed8cc6 100644 --- a/package.json +++ b/package.json @@ -10,5 +10,8 @@ "next-on-netlify": "^2.0.0", "react": "^16.13.1", "react-dom": "^16.13.1" + }, + "devDependencies": { + "buffer-loader": "^0.1.0" } } diff --git a/pages/api/[...slug].js b/pages/api/[...slug].js new file mode 100644 index 0000000..b5b459e --- /dev/null +++ b/pages/api/[...slug].js @@ -0,0 +1,41 @@ +export default async (req, res) => { + // Get the ID to show + const { query } = req + const { slug } = query + const id = slug[0] + + // Get the data + const fetchRes = await fetch(`https://api.tvmaze.com/shows/${id}`); + const show = await fetchRes.json(); + + // Show could not be found + if(fetchRes.status > 200) { + res.status(404) + res.json({ + error: 'Show could not be found :(' + }) + return + } + + res.status(200) + res.json({ + title: 'API route: catch-all endpoint', + description: 'This endpoint fetches a TV show from an external API. ' + + 'It is a catch-all endpoint. ' + + 'The first URL parameter determines the ID of the show to fetch. ' + + 'You can change the URL to anything else, such as /api/1871/whatever/path/you/want', + slug: slug, + viewCode: 'https://github.com/FinnWoelm/next-on-netlify-demo/tree/master/pages/api/[...slug].js', + goHome: 'https://next-on.netlify.app', + show: { + id: show.id, + name: show.name, + type: show.type, + language: show.language, + status: show.status, + premiered: show.premiered, + officialSite: show.officialSite, + averageRating: show.rating?.average + } + }) +} diff --git a/pages/api/[id].js b/pages/api/[id].js new file mode 100644 index 0000000..48ed937 --- /dev/null +++ b/pages/api/[id].js @@ -0,0 +1,38 @@ +export default async (req, res) => { + // Get the ID to show + const { query } = req + const { id } = query + + // Get the data + const fetchRes = await fetch(`https://api.tvmaze.com/shows/${id}`); + const show = await fetchRes.json(); + + // Show could not be found + if(fetchRes.status > 200) { + res.status(404) + res.json({ + error: 'Show could not be found :(' + }) + return + } + + res.status(200) + res.json({ + title: 'API route: dynamic endpoint', + description: 'This endpoint fetches a TV show from an external API. ' + + 'The ID is set in the URL: /api/:id. ' + + 'You can change the ID to any number between 1-10000. Try it!', + viewCode: 'https://github.com/FinnWoelm/next-on-netlify-demo/tree/master/pages/api/[id].js', + goHome: 'https://next-on.netlify.app', + show: { + id: show.id, + name: show.name, + type: show.type, + language: show.language, + status: show.status, + premiered: show.premiered, + officialSite: show.officialSite, + averageRating: show.rating?.average + } + }) +} diff --git a/pages/api/enterPreview/[id].js b/pages/api/enterPreview/[id].js new file mode 100644 index 0000000..0fbca07 --- /dev/null +++ b/pages/api/enterPreview/[id].js @@ -0,0 +1,12 @@ +export default (req, res) => { + // Get the ID to redirect to + const { query } = req + const { id } = query + + // Enable Preview Mode by setting preview mode cookies + res.setPreviewData({}) + + // Redirect to a page with support for preview mode + res.writeHead(307, { Location: `/previewMode/${id}` }) + res.end() +} diff --git a/pages/api/exitPreview/[id].js b/pages/api/exitPreview/[id].js new file mode 100644 index 0000000..c8f8b06 --- /dev/null +++ b/pages/api/exitPreview/[id].js @@ -0,0 +1,13 @@ +export default (req, res) => { + // Get the ID to redirect to + const { query } = req + const { id } = query + + // Clear the preview mode cookies. + // This function accepts no arguments. + res.clearPreviewData() + + // Redirect to a page with support for preview mode + res.writeHead(307, { Location: `/previewMode/${id}` }) + res.end() +} diff --git a/pages/api/image.js b/pages/api/image.js new file mode 100644 index 0000000..5a210f1 --- /dev/null +++ b/pages/api/image.js @@ -0,0 +1,10 @@ +import roll from 'buffer-loader!../../roll.jpg' + +export default (req, res) => { + res.status(200) + res.setHeader('Content-Type', 'image/jpeg') + // Send the image buffer. There are many other ways to send images and other + // files. For example, you can create a buffer from a base64-encoded string + // of an image: https://stackoverflow.com/a/28440633/6451879 + res.send(roll) +} diff --git a/pages/api/redirect.js b/pages/api/redirect.js new file mode 100644 index 0000000..e799276 --- /dev/null +++ b/pages/api/redirect.js @@ -0,0 +1,4 @@ +export default (req, res) => { + res.writeHead(307, { Location: '/you-have-been-redirected' }) + res.end() +} diff --git a/pages/api/show.js b/pages/api/show.js new file mode 100644 index 0000000..89ef06c --- /dev/null +++ b/pages/api/show.js @@ -0,0 +1,11 @@ +export default (req, res) => { + res.status(200) + res.json({ + title: 'API route: basic endpoint', + description: 'API endpoints are handled by Netlify Functions. ' + + 'You can run all sorts of code and return all sorts of responses. ' + + 'This one simply returns some JSON.', + viewCode: 'https://github.com/FinnWoelm/next-on-netlify-demo/tree/master/pages/api/show.js', + goHome: 'https://next-on.netlify.app' + }) +} diff --git a/pages/api/xml.js b/pages/api/xml.js new file mode 100644 index 0000000..8672e2d --- /dev/null +++ b/pages/api/xml.js @@ -0,0 +1,13 @@ +export default (req, res) => { + res.status(200) + res.setHeader('Content-Type', 'application/xml') + res.send( + ` + + API route: with content-type XML + API endpoints are handled by Netlify Functions. This one returns XML. + https://github.com/FinnWoelm/next-on-netlify-demo/tree/master/pages/api/xml.js + https://next-on.netlify.app + ` + ) +} diff --git a/pages/getInitialProps/[...slug].js b/pages/getInitialProps/[...slug].js new file mode 100644 index 0000000..8170486 --- /dev/null +++ b/pages/getInitialProps/[...slug].js @@ -0,0 +1,82 @@ +import Error from 'next/error' +import Link from 'next/link' + +const CatchAllShow = ({ errorCode, show, slug }) => { + + // If show was not found, render 404 page + if (errorCode) { + return + } + + // Otherwise, render the page + return ( + <> +

getInitialProps: with catch-all routing

+

+ This page uses getInitialProps() to fetch a TV show from an API.
+ It uses catch-all routing. +

+

+ URL parameters are made available in getInitialProps: +
+ {slug.map((item, index) => ( + + [{index}]: {item}
+
+ ))} +

+

+ The first URL parameter determines the ID of the TV show to fetch. +

+

+ You can change the URL to anything else, such as /getInitialProps/1871/whatever/path/you/want. Try it! +

+ + View code on GitHub + + +
+ +

Show #{show.id}: {show.name}

+ + https://api.tvmaze.com/shows/{show.id} + + +

+ Type: {show.type}
+ Language: {show.language}
+ Status: {show.status}
+ Premiered: {show.premiered}
+ Official Site: {show.officialSite}
+ Rating (average): {show.rating?.average} +

+ +
+ + + Go back home + + + ) +} + +CatchAllShow.getInitialProps = async ({ query }) => { + // Get the ID to render + const { slug } = query + const id = slug[0] + + // Get the show + const res = await fetch(`https://api.tvmaze.com/shows/${id}`); + const show = await res.json(); + + // Set error code if show could not be found + const errorCode = res.status > 200 ? res.status : false + + return { errorCode, show, slug } +} + +export default CatchAllShow diff --git a/pages/getInitialProps/[id].js b/pages/getInitialProps/[id].js new file mode 100644 index 0000000..95844bf --- /dev/null +++ b/pages/getInitialProps/[id].js @@ -0,0 +1,69 @@ +import Error from 'next/error' +import Link from 'next/link' + +const DynamicShow = ({ errorCode, show }) => { + + // If show was not found, render 404 page + if (errorCode) { + return + } + + // Otherwise, render show + return ( + <> +

getInitialProps: with dynamic routing

+

+ This page uses getInitialProps() to fetch a TV show from an API.
+ The ID is set in the URL: /getInitialProps/:id +

+

+ You can change the ID to any number between 1-10000. Try it! +

+ + View code on GitHub + + +
+ +

Show #{show.id}: {show.name}

+ + https://api.tvmaze.com/shows/{show.id} + + +

+ Type: {show.type}
+ Language: {show.language}
+ Status: {show.status}
+ Premiered: {show.premiered}
+ Official Site: {show.officialSite}
+ Rating (average): {show.rating?.average} +

+ +
+ + + Go back home + + + ) +} + +DynamicShow.getInitialProps = async ({ query }) => { + // Get the ID to render + const { id } = query + + // Get the data + const res = await fetch(`https://api.tvmaze.com/shows/${id}`); + const show = await res.json(); + + // Set error code if show could not be found + const errorCode = res.status > 200 ? res.status : false + + return { errorCode, show } +} + +export default DynamicShow diff --git a/pages/getInitialProps/show.js b/pages/getInitialProps/show.js new file mode 100644 index 0000000..0f7ddf7 --- /dev/null +++ b/pages/getInitialProps/show.js @@ -0,0 +1,54 @@ +import Link from 'next/link' + +const Show = ({ show }) => ( + <> +

getInitialProps: basic page

+

+ This page uses getInitialProps() to fetch a TV show from an API. +

+

+ When navigating client-side, getInitialProps() runs on the client. +
+ When requesting this page directly, the page is rendered server-side by a Netlify Function. +

+ + View code on GitHub + + +
+ +

Show #{show.id}: {show.name}

+ + https://api.tvmaze.com/shows/{show.id} + + +

+ Type: {show.type}
+ Language: {show.language}
+ Status: {show.status}
+ Premiered: {show.premiered}
+ Official Site: {show.officialSite}
+ Rating (average): {show.rating?.average} +

+ +
+ + + Go back home + + +) + +Show.getInitialProps = async () => { + // Get the show + const res = await fetch('https://api.tvmaze.com/shows/768'); + const show = await res.json(); + + return { show } +} + +export default Show diff --git a/pages/getServerSideProps/[...slug].js b/pages/getServerSideProps/[...slug].js new file mode 100644 index 0000000..480fe0e --- /dev/null +++ b/pages/getServerSideProps/[...slug].js @@ -0,0 +1,81 @@ +import Error from 'next/error' +import Link from 'next/link' + +const CatchAllShow = ({ errorCode, show, slug }) => { + + // If show was not found, render 404 page + if (errorCode) { + return + } + + return ( + <> +

getServerSideProps: with catch-all routing

+

+ This page uses getServerSideProps() to fetch a TV show from an API.
+ It uses catch-all routing. +

+

+ URL parameters are made available in getServerSideProps: +
+ {slug.map((item, index) => ( + + [{index}]: {item}
+
+ ))} +

+

+ The first URL parameter determines the ID of the TV show to fetch. +

+

+ You can change the URL to anything else, such as /getServerSideProps/112/whatever/path/you/want. Try it! +

+ + View code on GitHub + + +
+ +

Show #{show.id}: {show.name}

+ + https://api.tvmaze.com/shows/{show.id} + + +

+ Type: {show.type}
+ Language: {show.language}
+ Status: {show.status}
+ Premiered: {show.premiered}
+ Official Site: {show.officialSite}
+ Rating (average): {show.rating?.average} +

+ +
+ + + Go back home + + + ) +} + +export async function getServerSideProps({ params }) { + // Get the ID to render + const { slug } = params + const id = slug[0] + + // Get the data + const res = await fetch(`https://api.tvmaze.com/shows/${id}`); + const show = await res.json(); + + // Set error code if show could not be found + const errorCode = res.status > 200 ? res.status : false + + return { props: { errorCode, show, slug } } +} + +export default CatchAllShow diff --git a/pages/getServerSideProps/[id].js b/pages/getServerSideProps/[id].js new file mode 100644 index 0000000..9f47c7d --- /dev/null +++ b/pages/getServerSideProps/[id].js @@ -0,0 +1,68 @@ +import Error from 'next/error' +import Link from 'next/link' + +const DynamicShow = ({ errorCode, show }) => { + + // If show was not found, render 404 page + if (errorCode) { + return + } + + return ( + <> +

getServerSideProps: with dynamic routing

+

+ This page uses getServerSideProps() to fetch a TV show from an API.
+ The ID is set in the URL: /getServerSideProps/:id +

+

+ You can change the ID to any number between 1-10000. Try it! +

+ + View code on GitHub + + +
+ +

Show #{show.id}: {show.name}

+ + https://api.tvmaze.com/shows/{show.id} + + +

+ Type: {show.type}
+ Language: {show.language}
+ Status: {show.status}
+ Premiered: {show.premiered}
+ Official Site: {show.officialSite}
+ Rating (average): {show.rating?.average} +

+ +
+ + + Go back home + + + ) +} + +export async function getServerSideProps({ params }) { + // Get the ID to render + const { id } = params + + // Get the data + const res = await fetch(`https://api.tvmaze.com/shows/${id}`); + const show = await res.json(); + + // Set error code if show could not be found + const errorCode = res.status > 200 ? res.status : false + + return { props: { errorCode, show } } +} + +export default DynamicShow diff --git a/pages/getServerSideProps/show.js b/pages/getServerSideProps/show.js new file mode 100644 index 0000000..9b4abab --- /dev/null +++ b/pages/getServerSideProps/show.js @@ -0,0 +1,58 @@ +import Link from 'next/link' + +const Show = ({ show }) => ( + <> +

getServerSideProps: basic page

+

+ This page uses getServerSideProps() to fetch a TV show from an API. +

+

+ getServerSideProps() never runs on the client. +
+ When navigating client-side, getServerSideProps() runs inside a Netlify + Function. The resulting JSON data is used to render this page. +
+ When requesting this page directly, the entire page is rendered + server-side by a Netlify Function. +

+ + View code on GitHub + + +
+ +

Show #{show.id}: {show.name}

+ + https://api.tvmaze.com/shows/{show.id} + + +

+ Type: {show.type}
+ Language: {show.language}
+ Status: {show.status}
+ Premiered: {show.premiered}
+ Official Site: {show.officialSite}
+ Rating (average): {show.rating?.average} +

+ +
+ + + Go back home + + +) + +export async function getServerSideProps() { + // Get the show + const res = await fetch('https://api.tvmaze.com/shows/263'); + const show = await res.json(); + + return { props: { show } } +} + +export default Show diff --git a/pages/getStaticProps/[...slug].js b/pages/getStaticProps/[...slug].js new file mode 100644 index 0000000..92a0934 --- /dev/null +++ b/pages/getStaticProps/[...slug].js @@ -0,0 +1,109 @@ +import Link from 'next/link' + +const CatchAllShow = ({ show, slug }) => ( + <> +

getStaticProps: with catch-all routing

+

+ This page uses getStaticProps() to fetch a TV show from an API.
+ It uses catch-all routing. +

+

+ Because the page uses catch-all routing, the list of paths are + pre-defined in getStaticPaths. +
+ For this page, you can choose between one of the following pre-defined + paths: +

+ + + View code on GitHub + + +
+ +

Show #{show.id}: {show.name}

+ + https://api.tvmaze.com/shows/{show.id} + + +

+ Type: {show.type}
+ Language: {show.language}
+ Status: {show.status}
+ Premiered: {show.premiered}
+ Official Site: {show.officialSite}
+ Rating (average): {show.rating?.average} +

+ +
+ + + Go back home + + +) + +export async function getStaticPaths() { + // Define the paths we want to prerender + const paths = [ + { params: { slug: ['1719', 'mr', 'bean' ] } }, + { params: { slug: ['143', 'silicon', 'valley' ] } }, + { params: { slug: ['490', 'star', 'trek' ] } }, + { params: { slug: ['431', 'friends' ] } }, + { params: { slug: ['361', 'saturday', 'night', 'live' ] } }, + { params: { slug: ['6544', 'sesame', 'street' ] } }, + ] + + // We'll pre-render only these paths at build time. + // { fallback: false } means other routes should 404. + return { paths, fallback: false } +} + +export async function getStaticProps({ params }) { + // Get the ID to render + const { slug } = params + const id = slug[0] + + // Get the data + const res = await fetch(`https://api.tvmaze.com/shows/${id}`); + const show = await res.json(); + + return { props: { show, slug } } +} + +export default CatchAllShow diff --git a/pages/getStaticProps/[id].js b/pages/getStaticProps/[id].js new file mode 100644 index 0000000..057924d --- /dev/null +++ b/pages/getStaticProps/[id].js @@ -0,0 +1,71 @@ +import Link from 'next/link' + +const DynamicShow = ({ show }) => ( + <> +

getStaticProps: with dynamic routing

+

+ This page uses getStaticProps() to fetch a TV show from an API.
+ The ID is set in the URL: /getStaticProps/:id +

+

+ Because the page uses dynamic routing, the list of paths are pre-defined + in getStaticPaths. +
+ For this page, you can change the ID to any number between 1-100. Try it! +

+ + View code on GitHub + + +
+ +

Show #{show.id}: {show.name}

+ + https://api.tvmaze.com/shows/{show.id} + + +

+ Type: {show.type}
+ Language: {show.language}
+ Status: {show.status}
+ Premiered: {show.premiered}
+ Official Site: {show.officialSite}
+ Rating (average): {show.rating?.average} +

+ +
+ + + Go back home + + +) + +export async function getStaticPaths() { + // Define the paths we want to prerender + const paths = [] + for(let id = 1; id <= 100; id++) { + paths.push({ params: { id: String(id) }}) + } + + // We'll pre-render only these paths at build time. + // { fallback: false } means other routes should 404. + return { paths, fallback: false } +} + +export async function getStaticProps({ params }) { + // Get the ID to render + const { id } = params + + // Get the data + const res = await fetch(`https://api.tvmaze.com/shows/${id}`); + const show = await res.json(); + + return { props: { show } } +} + +export default DynamicShow diff --git a/pages/getStaticProps/show.js b/pages/getStaticProps/show.js new file mode 100644 index 0000000..dabc114 --- /dev/null +++ b/pages/getStaticProps/show.js @@ -0,0 +1,57 @@ +import Link from 'next/link' + +const Show = ({ show }) => ( + <> +

getStaticProps: basic page

+

+ This page uses getStaticProps() to fetch a TV show from an API. +

+

+ The page and the page's data are pre-rendered at build time. + Both are served from Netlify's super fast CDN. +
+ When navigating client-side, the page's JSON data is loaded. +
+ When requesting this page directly, the pre-rendered page is loaded. +

+ + View code on GitHub + + +
+ +

Show #{show.id}: {show.name}

+ + https://api.tvmaze.com/shows/{show.id} + + +

+ Type: {show.type}
+ Language: {show.language}
+ Status: {show.status}
+ Premiered: {show.premiered}
+ Official Site: {show.officialSite}
+ Rating (average): {show.rating?.average} +

+ +
+ + + Go back home + + +) + +export async function getStaticProps() { + // Get the show + const res = await fetch('https://api.tvmaze.com/shows/151'); + const show = await res.json(); + + return { props: { show } } +} + +export default Show diff --git a/pages/getStaticProps/withFallback/[id].js b/pages/getStaticProps/withFallback/[id].js new file mode 100644 index 0000000..10a941b --- /dev/null +++ b/pages/getStaticProps/withFallback/[id].js @@ -0,0 +1,96 @@ +import Error from 'next/error' +import Link from 'next/link' +import { useRouter } from 'next/router' + +const DynamicShow = ({ errorCode, show }) => { + const router = useRouter() + + // On Netlify, isFallback is NEVER true. Pages for any undefined paths are + // always server-side-rendered. + // See: https://github.com/FinnWoelm/next-on-netlify#fallbacks-for-pages-with-getstaticpaths + if (router.isFallback) { + return
Loading... (This only renders when using next dev)
+ } + + // If show was not found, render 404 page + if (errorCode) { + return + } + + return ( + <> +

getStaticProps: with fallback: true

+

+ This page uses getStaticProps() to fetch a TV show from an API.
+ The ID is set in the URL: /getStaticProps/withFallback/:id +

+

+ The page uses dynamic routing and some paths are pre-defined in + getStaticPaths (IDs 1-10). +
+ If you request one of those pages, you will see the pre-rendered HTML + page. +
+ If you load this page with any other ID (e.g., 32), the page will be + rendered server-side by a Netlify Function. +

+ + View code on GitHub + + +
+ +

Show #{show.id}: {show.name}

+ + https://api.tvmaze.com/shows/{show.id} + + +

+ Type: {show.type}
+ Language: {show.language}
+ Status: {show.status}
+ Premiered: {show.premiered}
+ Official Site: {show.officialSite}
+ Rating (average): {show.rating?.average} +

+ +
+ + + Go back home + + + ) +} + +export async function getStaticPaths() { + // Define the paths we want to prerender + const paths = [] + for(let id = 1; id <= 10; id++) { + paths.push({ params: { id: String(id) }}) + } + + // We'll pre-render only these paths at build time. + // { fallback: true } means other routes will be server-side rendered. + return { paths, fallback: true } +} + +export async function getStaticProps({ params }) { + // Get the ID to render + const { id } = params + + // Get the data + const res = await fetch(`https://api.tvmaze.com/shows/${id}`); + const show = await res.json(); + + // Set error code if show could not be found + const errorCode = res.status > 200 ? res.status : false + + return { props: { errorCode, show } } +} + +export default DynamicShow diff --git a/pages/index.js b/pages/index.js index 784e088..8d810e3 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,12 +1,31 @@ import Link from 'next/link' -const Index = ({ shows }) => ( -
- NextJS on Netlify Banner +const Index = () => ( + <> +
+ NextJS on Netlify Banner +
+
+ + NPM version + + {' '} + + MIT license + + {' '} + + NPM downloads + + {' '} + + Tested with Cypress.io + +
-

NextJS on Netlify

+

NextJS on Netlify: Server-Side Rendering Made Easy

This is a demo of a NextJS application with Server-Side Rendering (SSR).
@@ -24,114 +43,143 @@ const Index = ({ shows }) => ( npm package.

-

1. Server-Side Rendering Made Easy

-

- This page is server-side rendered. -
- It fetches a random list of five TV shows - from the TVmaze REST API. -
- Refresh this page to see it change. -

+
+

Examples

+

getInitialProps

-

2. Full Support for Dynamic Pages

-

- Dynamic pages, introduced in NextJS 9.2, are fully supported. -
- Click on a show to check out a server-side rendered page with dynamic - routing (/shows/:id). -

- +

getServerSideProps

-

3. Catch-All Routes? Included ✔

-

You can even take advantage of - {' '} - - NextJS' catch-all routes feature - . -
- Here are three examples: -

+

getStaticProps

-

4. Static Pages Stay Static

-

- next-on-netlify automatically determines which pages are dynamic and - which ones are static. -
- Only dynamic pages are server-side rendered. -
- Static pages are pre-rendered and served directly by Netlify's CDN. -

+

API Routes

+ +

Preview Mode

+
+

Want to Learn More?

- Check out the + Check out this demo's {' '} source code on GitHub - . + + . +
+ Or check out the + {' '} + + next-on-netlify npm package + + .

-
+ ) -Index.getInitialProps = async function() { - // Set a random page between 1 and 100 - const randomPage = Math.floor(Math.random()*100) + 1 - - // Get the data - const res = await fetch(`https://api.tvmaze.com/shows?page=${randomPage}`); - const data = await res.json(); - - return { shows: data.slice(0, 5) } -} - export default Index diff --git a/pages/previewMode/[id].js b/pages/previewMode/[id].js new file mode 100644 index 0000000..6c3407a --- /dev/null +++ b/pages/previewMode/[id].js @@ -0,0 +1,122 @@ +import Error from 'next/error' +import Link from 'next/link' + +const DynamicShow = ({ errorCode, object, preview }) => { + + // If object was not found, render 404 page + if (errorCode) { + return + } + + return ( + <> +

Preview Mode: page with preview mode

+

+ This page uses getServerSideProps() to fetch either + a TV show or a TV actor depending on whether preview mode is enabled. +
+ The ID is set in the URL: /previewMode/:id +

+

+ You can change the ID to any number between 1-10000. Try it! +

+

+ + View code for this page GitHub + +

+

+ + View code for 'enter' API endpoint on GitHub + +

+

+ + View code for 'exit' API endpoint on GitHub + +

+ +
+ + {preview ? ( + <> +

+ You are currently in preview mode. + {' '} + + Exit preview mode. + +

+

Actor #{object.id}: {object.name}

+ + https://api.tvmaze.com/people/{object.id} + + +

+ Country: {object.country?.name}
+ Gender: {object.gender}
+ Timezone: {object.country?.timezone}
+

+ + ) : ( + <> +

+ You are currently not in preview mode. + {' '} + + Enter preview mode. + +

+

Show #{object.id}: {object.name}

+ + https://api.tvmaze.com/shows/{object.id} + + +

+ Type: {object.type}
+ Language: {object.language}
+ Status: {object.status}
+ Premiered: {object.premiered}
+ Official Site: {object.officialSite}
+ Rating (average): {object.rating?.average} +

+ + )} + +
+ + + Go back home + + + ) +} + +export async function getServerSideProps({ params, preview }) { + // Get the ID to render + const { id } = params + + // Set the resource to fetch, depending on whether preview mode is active + const resource = preview ? 'people' : 'shows' + + // Get the data + const res = await fetch(`https://api.tvmaze.com/${resource}/${id}`); + const object = await res.json(); + + // Set error code if object could not be found + const errorCode = res.status > 200 ? res.status : false + + return { props: { errorCode, object, preview: Boolean(preview) } } +} + +export default DynamicShow diff --git a/pages/shows/[...params].js b/pages/shows/[...params].js deleted file mode 100644 index d489aab..0000000 --- a/pages/shows/[...params].js +++ /dev/null @@ -1,64 +0,0 @@ -import Error from 'next/error' -import Link from 'next/link' - -const CatchAll = ({ errorCode, show, params }) => { - - // If show item was not found, render 404 page - if (errorCode) { - return - } - - // Otherwise, render show - return ( -
-

- This is a server-side rendered catch-all page. It catches all requests - made to /shows/:id/any/path/can/go/here... and makes those parameters - available in getInitialProps(): -
- {params.map((param, index) => ( - - [{index}]: {param}
-
- ))} -
- Refresh the page to see server-side rendering in action. -
- You can also try changing the URL to something random, - such as /shows/{show.id}/whatever/path/you/want -

- -
- -

Show #{show.id}

-

- {show.name} -

- -
- - - Go back home - -
- ) -} - -CatchAll.getInitialProps = async ({ res: req, query }) => { - // Get the params to render - const { params } = query - - // Get the ID to render - const id = params[0] - - // Get the data - const res = await fetch(`https://api.tvmaze.com/shows/${id}`); - const data = await res.json(); - - // Set error code if show item could not be found - const errorCode = res.status > 200 ? res.status : false - - return { errorCode, show: data, params } -} - -export default CatchAll diff --git a/pages/shows/[id].js b/pages/shows/[id].js deleted file mode 100644 index c724dbd..0000000 --- a/pages/shows/[id].js +++ /dev/null @@ -1,53 +0,0 @@ -import Error from 'next/error' -import Link from 'next/link' - -const Show = ({ errorCode, show }) => { - - // If show item was not found, render 404 page - if (errorCode) { - return - } - - // Otherwise, render show - return ( -
-

- This page uses getInitialProps() to fetch the show with the ID - provided in the URL: /shows/:id -
- Refresh the page to see server-side rendering in action. -
- You can also try changing the ID to any other number between 1-10000. -

- -
- -

Show #{show.id}

-

- {show.name} -

- -
- - - Go back home - -
- ) -} - -Show.getInitialProps = async ({ res: req, query }) => { - // Get the ID to render - const { id } = query - - // Get the data - const res = await fetch(`https://api.tvmaze.com/shows/${id}`); - const data = await res.json(); - - // Set error code if show item could not be found - const errorCode = res.status > 200 ? res.status : false - - return { errorCode, show: data } -} - -export default Show diff --git a/pages/static.js b/pages/static.js deleted file mode 100644 index 53a2f3b..0000000 --- a/pages/static.js +++ /dev/null @@ -1,27 +0,0 @@ -import Link from 'next/link' - -const Static = props => ( -
-

- This page does not use getInitialProps. -
- It is a static page. -
- It is never server-side rendered. -
- It is served directly by Netlify's CDN. -
- The next-on-netlify npm - package takes care of deciding which pages to render server-side and which - ones to serve directly via CDN. -

- -
- - - Go back home - -
-) - -export default Static diff --git a/pages/static/[id].js b/pages/static/[id].js deleted file mode 100644 index 9904b40..0000000 --- a/pages/static/[id].js +++ /dev/null @@ -1,33 +0,0 @@ -import Link from 'next/link' - -const StaticWithID = props => ( -
-

- This page does not use getInitialProps. -
- It is a static page. -
- It is never server-side rendered. -
- It is served directly by Netlify's CDN. -
-
- But it has a dynamic URL parameter: /static/:id. -
- Try changing the ID. It will always render this page, no matter what you - put. -
- I am not sure what this is useful for. -
- But it's a feature of NextJS, so... I'm supporting it. -

- -
- - - Go back home - -
-) - -export default StaticWithID diff --git a/pages/you-have-been-redirected.js b/pages/you-have-been-redirected.js new file mode 100644 index 0000000..10676d0 --- /dev/null +++ b/pages/you-have-been-redirected.js @@ -0,0 +1,30 @@ +import Link from 'next/link' + +const RedirectionTarget = props => ( +
+

You have been redirected!

+

+ The API endpoint redirected you to this static page. +

+

+ + View code for API endpoint on GitHub + +

+

+ + Visit API endpoint with redirect header again + +

+ +
+ + + Go back home + +
+) + +export default RedirectionTarget diff --git a/roll.jpg b/roll.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a437347c4dfd10935b6148e2ab64d94cc21e023b GIT binary patch literal 47668 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 ))Y78n|tKVrlCl{C&ksG2DF*M=H>(Yg#@C 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 Date: Thu, 16 Jul 2020 07:29:39 +0200 Subject: [PATCH 2/3] Update next-on-netlify to v2.3.0 v2.3.0 adds support for preview mode, among other things. Full changelog for next-on-netlify is available here: https://github.com/FinnWoelm/next-on-netlify/blob/master/CHANGELOG.md --- package-lock.json | 40 ++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 631aeda..fa5fe5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1666,11 +1666,11 @@ "integrity": "sha512-WT9LheDC4/d/sD/jgC6L5UMq4U9X3KNMy0JrXp/MdJL83ZqcuPQuMkj50beOX0dMub8IoZUYycfN7bIVZuU5zg==" }, "acorn-class-fields": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/acorn-class-fields/-/acorn-class-fields-0.3.4.tgz", - "integrity": "sha512-yqUCIu0UJHFmCVhH3Cq29UR+3OJo1CtNWf1ncxTf3KfdEDt7aD0iVYmX7UN+RvIHyOsgukzplQhNkgePtASLUw==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/acorn-class-fields/-/acorn-class-fields-0.3.6.tgz", + "integrity": "sha512-nOzMl1byCFAJLgxNUG7QorpzRHWlkBKVSSOMKUu+bVbVZG5lU4NZkOp/uA7CnE+NAsWhmxTsMgQdHsQXUO8Ulg==", "requires": { - "acorn-private-class-elements": "^0.2.5" + "acorn-private-class-elements": "^0.2.6" } }, "acorn-dynamic-import": { @@ -1689,16 +1689,16 @@ "integrity": "sha512-pshgiVR5mhpjFVdizKTN+kAGRqjJFUOEB3TvpQ6kiAutb1lvHrIVVcGoe5xzMpJkVNifCeymMG7/tsDkWn8CdQ==" }, "acorn-private-class-elements": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/acorn-private-class-elements/-/acorn-private-class-elements-0.2.5.tgz", - "integrity": "sha512-3eApRrJmPjaxWB3XidP8YMeVq9pcswPFE0KsSWVuhceCU68ZS8fkcf0fTXGhCmnNd7n48NWWV27EKMFPeCoJLg==" + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/acorn-private-class-elements/-/acorn-private-class-elements-0.2.6.tgz", + "integrity": "sha512-PV+AhOU1/vCx5zIBgGYLB5+OoT8IPKZUcWEGdLBTQgFBMMzPM9S5SKSG4EdiuULqoq3pV3C07rGuSC1Y5gbi/g==" }, "acorn-private-methods": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/acorn-private-methods/-/acorn-private-methods-0.3.1.tgz", - "integrity": "sha512-IV5XZInFQaQK5ucjJy/HAk2UYvt+Buax00evzwo8NSuo8zhOBhW5v6VOjAljYUhAzQ/Hosi+Kaz6xJmvPiSM4Q==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/acorn-private-methods/-/acorn-private-methods-0.3.2.tgz", + "integrity": "sha512-jTgRNDbEkbtxOIPUmDZ4u4oDGCO4tNPDNeW+jJrkbLl/Hzl9EVLva+kGQ289irSPhxi7FI9TjuXmIiqjnJcj9w==", "requires": { - "acorn-private-class-elements": "^0.2.4" + "acorn-private-class-elements": "^0.2.6" } }, "adjust-sourcemap-loader": { @@ -3301,9 +3301,9 @@ } }, "execa": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", - "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", "requires": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -4819,14 +4819,14 @@ } }, "next-aws-lambda": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/next-aws-lambda/-/next-aws-lambda-2.4.1.tgz", - "integrity": "sha512-GdRUJdCMuBaMhn4PdCd07+rB2NCkw8S9OM5I9Pag6XUgyKpuTFOc+wmCR9nIvM3yPina7uuoBdLnP6am6gJQsA==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/next-aws-lambda/-/next-aws-lambda-2.5.0.tgz", + "integrity": "sha512-TKI0e+RFOuevQnkliE73VCzx9VRF8qpXuL18uxOJvPhCe09pxLwfaDQMuNKf3b2d9PS/Ajn+Y/O41bBuJMu4aA==" }, "next-on-netlify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/next-on-netlify/-/next-on-netlify-2.0.0.tgz", - "integrity": "sha512-Z6NJZFlfMckyTjsYfnduPe9+hP6rYdhyTffjGRcxEOkf2bQL8T+qrvxP2O789GddVhZFZVciQ75jgjOmX009Jg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/next-on-netlify/-/next-on-netlify-2.3.0.tgz", + "integrity": "sha512-zTQT5sKIXKrK0ghRU/PgM82H2qV1yTtrhFt+4EYLAc2T/DdYxqZ3lEJvO9yCZUxEQ/2VYKYM0he98UPdSn/Dlg==", "requires": { "@sls-next/lambda-at-edge": "1.2.0-alpha.3", "fs-extra": "^9.0.0", diff --git a/package.json b/package.json index 7ed8cc6..990f276 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "next": "^9.4.4", - "next-on-netlify": "^2.0.0", + "next-on-netlify": "^2.3.0", "react": "^16.13.1", "react-dom": "^16.13.1" }, From 7e6f93616bf779fc5e68aecefd71eb2e2b8a2ae1 Mon Sep 17 00:00:00 2001 From: Finn Woelm Date: Sat, 5 Sep 2020 20:43:24 +0200 Subject: [PATCH 3/3] Test base64 support Try to set base64 support to true. --- package-lock.json | 160 ++++++++++++++++++++++++++++ package.json | 2 + patches/next-on-netlify+2.3.0.patch | 15 +++ 3 files changed, 177 insertions(+) create mode 100644 patches/next-on-netlify+2.3.0.patch diff --git a/package-lock.json b/package-lock.json index fa5fe5e..702fbe5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1582,6 +1582,11 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" + }, "@zeit/node-file-trace": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@zeit/node-file-trace/-/node-file-trace-0.5.1.tgz", @@ -2397,6 +2402,11 @@ "tslib": "^1.9.0" } }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -3513,6 +3523,40 @@ "locate-path": "^2.0.0" } }, + "find-yarn-workspace-root": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz", + "integrity": "sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==", + "requires": { + "fs-extra": "^4.0.3", + "micromatch": "^3.1.4" + }, + "dependencies": { + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + } + } + }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -4086,6 +4130,14 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, "is-color-stop": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", @@ -4325,6 +4377,14 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, + "klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "requires": { + "graceful-fs": "^4.1.11" + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -4838,6 +4898,11 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", @@ -5200,6 +5265,88 @@ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, + "patch-package": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.2.2.tgz", + "integrity": "sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg==", + "requires": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^1.2.1", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "path-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", @@ -6445,6 +6592,11 @@ } } }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -7109,6 +7261,14 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", diff --git a/package.json b/package.json index 990f276..c900647 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "next-on-netlify-demo", "scripts": { + "postinstall": "patch-package", "dev": "next", "build": "next build", "postbuild": "next-on-netlify" @@ -8,6 +9,7 @@ "dependencies": { "next": "^9.4.4", "next-on-netlify": "^2.3.0", + "patch-package": "^6.2.2", "react": "^16.13.1", "react-dom": "^16.13.1" }, diff --git a/patches/next-on-netlify+2.3.0.patch b/patches/next-on-netlify+2.3.0.patch new file mode 100644 index 0000000..b3bfe59 --- /dev/null +++ b/patches/next-on-netlify+2.3.0.patch @@ -0,0 +1,15 @@ +diff --git a/node_modules/next-on-netlify/lib/netlifyFunctionTemplate.js b/node_modules/next-on-netlify/lib/netlifyFunctionTemplate.js +index f9fd1ab..4e65227 100644 +--- a/node_modules/next-on-netlify/lib/netlifyFunctionTemplate.js ++++ b/node_modules/next-on-netlify/lib/netlifyFunctionTemplate.js +@@ -24,6 +24,10 @@ const callbackHandler = callback => ( + ) + + exports.handler = (event, context, callback) => { ++ // Enable base64 support ++ console.log(process.env); ++ process.env.BINARY_SUPPORT = "yes"; ++ + // In netlify dev, we currently do not receive headers as multi value headers. + // So we manually set them from the plain headers. This should become + // redundant as soon as https://github.com/netlify/cli/pull/938 is published.