diff --git a/.netlify/state.json b/.netlify/state.json new file mode 100644 index 0000000000..78ad1848cb --- /dev/null +++ b/.netlify/state.json @@ -0,0 +1,3 @@ +{ + "siteId": "b7ec5732-32dc-4d00-9108-051d100b6d2e" +} \ No newline at end of file diff --git a/demo/.gitignore b/demo/.gitignore new file mode 100644 index 0000000000..852cbb950f --- /dev/null +++ b/demo/.gitignore @@ -0,0 +1,38 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel + +netlify/functions +.netlify/functions +.netlify/cache \ No newline at end of file diff --git a/demo/README.md b/demo/README.md new file mode 100644 index 0000000000..b12f3e33e7 --- /dev/null +++ b/demo/README.md @@ -0,0 +1,34 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. + +[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`. + +The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/demo/components/Header.js b/demo/components/Header.js new file mode 100644 index 0000000000..31c6d3f6eb --- /dev/null +++ b/demo/components/Header.js @@ -0,0 +1,3 @@ +export default function Header() { + return

header

+} diff --git a/demo/netlify.toml b/demo/netlify.toml new file mode 100644 index 0000000000..bffbe00028 --- /dev/null +++ b/demo/netlify.toml @@ -0,0 +1,11 @@ +[build] +command = "npm run build" +publish = "out/" +# Build for updates outside of the site +ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF .." + +[[plugins]] +package = ".." + +[[plugins]] +package = "@netlify/plugin-local-install-core" \ No newline at end of file diff --git a/demo/next.config.js b/demo/next.config.js new file mode 100644 index 0000000000..cceffb934b --- /dev/null +++ b/demo/next.config.js @@ -0,0 +1,5 @@ + + module.exports = { + target: 'serverless' + } + \ No newline at end of file diff --git a/demo/package.json b/demo/package.json new file mode 100644 index 0000000000..b26d22b5e7 --- /dev/null +++ b/demo/package.json @@ -0,0 +1,15 @@ +{ + "name": "demo", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "10.2.3", + "react": "17.0.2", + "react-dom": "17.0.2" + } +} diff --git a/demo/pages/_app.js b/demo/pages/_app.js new file mode 100644 index 0000000000..1e1cec9242 --- /dev/null +++ b/demo/pages/_app.js @@ -0,0 +1,7 @@ +import '../styles/globals.css' + +function MyApp({ Component, pageProps }) { + return +} + +export default MyApp diff --git a/demo/pages/api/hello-background.js b/demo/pages/api/hello-background.js new file mode 100644 index 0000000000..5808ea36cf --- /dev/null +++ b/demo/pages/api/hello-background.js @@ -0,0 +1,5 @@ +export default (req, res) => { + res.setHeader('Content-Type', 'application/json') + res.status(200) + res.json({ message: 'hello world :)' }) +} diff --git a/demo/pages/api/hello.js b/demo/pages/api/hello.js new file mode 100644 index 0000000000..9987aff4c3 --- /dev/null +++ b/demo/pages/api/hello.js @@ -0,0 +1,5 @@ +// Next.js API route support: https://nextjs.org/docs/api-routes/introduction + +export default (req, res) => { + res.status(200).json({ name: 'John Doe' }) +} diff --git a/demo/pages/api/shows/[...params].js b/demo/pages/api/shows/[...params].js new file mode 100644 index 0000000000..e8f510d08b --- /dev/null +++ b/demo/pages/api/shows/[...params].js @@ -0,0 +1,26 @@ +export default async (req, res) => { + // Respond with JSON + res.setHeader('Content-Type', 'application/json') + + // Get the params and query string parameters + const { query } = req + const { params, ...queryStringParams } = query + + // Get the ID of the show + const id = params[0] + + // Get the data + const fetchRes = await fetch(`https://api.tvmaze.com/shows/${id}`) + const data = await fetchRes.json() + + // If show was found, return it + if (fetchRes.status == 200) { + res.status(200) + res.json({ params, queryStringParams, show: data }) + } + // If show was not found, return error + else { + res.status(404) + res.json({ error: 'Show not found' }) + } +} diff --git a/demo/pages/api/shows/[id].js b/demo/pages/api/shows/[id].js new file mode 100644 index 0000000000..54f8a41b73 --- /dev/null +++ b/demo/pages/api/shows/[id].js @@ -0,0 +1,23 @@ +export default async (req, res) => { + // Respond with JSON + res.setHeader('Content-Type', 'application/json') + + // Get the ID of the show + const { query } = req + const { id } = query + + // Get the data + const fetchRes = await fetch(`https://api.tvmaze.com/shows/${id}`) + const data = await fetchRes.json() + + // If show was found, return it + if (fetchRes.status == 200) { + res.status(200) + res.json({ show: data }) + } + // If show was not found, return error + else { + res.status(404) + res.json({ error: 'Show not found' }) + } +} diff --git a/demo/pages/deep/import.js b/demo/pages/deep/import.js new file mode 100644 index 0000000000..e2cb184911 --- /dev/null +++ b/demo/pages/deep/import.js @@ -0,0 +1,40 @@ +import Link from 'next/link' +import dynamic from 'next/dynamic' +const Header = dynamic(() => import(/* webpackChunkName: 'header' */ '../../components/Header'), { ssr: true }) + +const Show = ({ show }) => ( +
+
+

+ 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 + +
+) + +export const getServerSideProps = async ({ params }) => { + const res = await fetch('https://api.tvmaze.com/shows/42') + const data = await res.json() + + return { + props: { + show: data, + }, + } +} + +export default Show diff --git a/demo/pages/getServerSideProps/[id].js b/demo/pages/getServerSideProps/[id].js new file mode 100644 index 0000000000..3487e968de --- /dev/null +++ b/demo/pages/getServerSideProps/[id].js @@ -0,0 +1,53 @@ +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 + +
+ ) +} + +export const getServerSideProps = async ({ params }) => { + // The ID to render + const { id } = params + + 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 { + props: { + errorCode, + show: data, + }, + } +} + +export default Show diff --git a/demo/pages/getServerSideProps/all/[[...slug]].js b/demo/pages/getServerSideProps/all/[[...slug]].js new file mode 100644 index 0000000000..76230a787c --- /dev/null +++ b/demo/pages/getServerSideProps/all/[[...slug]].js @@ -0,0 +1,53 @@ +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 + +
+ ) +} + +export const getServerSideProps = async ({ params }) => { + // The ID to render + const { slug } = params + + const res = await fetch(`https://api.tvmaze.com/shows/${slug[0]}`) + const data = await res.json() + + // Set error code if show item could not be found + const errorCode = res.status > 200 ? res.status : false + + return { + props: { + errorCode, + show: data, + }, + } +} + +export default Show diff --git a/demo/pages/getServerSideProps/static.js b/demo/pages/getServerSideProps/static.js new file mode 100644 index 0000000000..dfbce6da56 --- /dev/null +++ b/demo/pages/getServerSideProps/static.js @@ -0,0 +1,37 @@ +import Link from 'next/link' + +const Show = ({ show }) => ( +
+

+ 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 + +
+) + +export const getServerSideProps = async ({ params }) => { + const res = await fetch('https://api.tvmaze.com/shows/42') + const data = await res.json() + + return { + props: { + show: data, + }, + } +} + +export default Show diff --git a/demo/pages/getStaticProps/[id].js b/demo/pages/getStaticProps/[id].js new file mode 100644 index 0000000000..089bef4cdb --- /dev/null +++ b/demo/pages/getStaticProps/[id].js @@ -0,0 +1,43 @@ +import Link from 'next/link' + +const Show = ({ show }) => ( +
+

This page uses getStaticProps() to pre-fetch a TV show.

+ +
+ +

Show #{show.id}

+

{show.name}

+ +
+ + + Go back home + +
+) + +export async function getStaticPaths() { + // Set the paths we want to pre-render + const paths = [{ params: { id: '1' } }, { params: { id: '2' } }] + + // 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 }) { + // The ID to render + const { id } = params + + const res = await fetch(`https://api.tvmaze.com/shows/${id}`) + const data = await res.json() + + return { + props: { + show: data, + }, + } +} + +export default Show diff --git a/demo/pages/getStaticProps/static.js b/demo/pages/getStaticProps/static.js new file mode 100644 index 0000000000..13d6428e22 --- /dev/null +++ b/demo/pages/getStaticProps/static.js @@ -0,0 +1,31 @@ +import Link from 'next/link' + +const Show = ({ show }) => ( +
+

This page uses getStaticProps() to pre-fetch a TV show.

+ +
+ +

Show #{show.id}

+

{show.name}

+ +
+ + + Go back home + +
+) + +export async function getStaticProps(context) { + const res = await fetch(`https://api.tvmaze.com/shows/71`) + const data = await res.json() + + return { + props: { + show: data, + }, + } +} + +export default Show diff --git a/demo/pages/getStaticProps/with-revalidate.js b/demo/pages/getStaticProps/with-revalidate.js new file mode 100644 index 0000000000..d3731601cb --- /dev/null +++ b/demo/pages/getStaticProps/with-revalidate.js @@ -0,0 +1,32 @@ +import Link from 'next/link' + +const Show = ({ show }) => ( +
+

This page uses getStaticProps() to pre-fetch a TV show.

+ +
+ +

Show #{show.id}

+

{show.name}

+ +
+ + + Go back home + +
+) + +export async function getStaticProps(context) { + const res = await fetch(`https://api.tvmaze.com/shows/71`) + const data = await res.json() + + return { + props: { + show: data, + }, + revalidate: 1, + } +} + +export default Show diff --git a/demo/pages/getStaticProps/withFallback/[...slug].js b/demo/pages/getStaticProps/withFallback/[...slug].js new file mode 100644 index 0000000000..8f004c9c01 --- /dev/null +++ b/demo/pages/getStaticProps/withFallback/[...slug].js @@ -0,0 +1,55 @@ +import { useRouter } from 'next/router' +import Link from 'next/link' + +const Show = ({ show }) => { + const router = useRouter() + + // This is never shown on Netlify. We just need it for NextJS to be happy, + // because NextJS will render a fallback HTML page. + if (router.isFallback) { + return
Loading...
+ } + + return ( +
+

This page uses getStaticProps() to pre-fetch a TV show.

+ +
+ +

Show #{show.id}

+

{show.name}

+ +
+ + + Go back home + +
+ ) +} + +export async function getStaticPaths() { + // Set the paths we want to pre-render + const paths = [{ params: { slug: ['my', 'path', '1'] } }, { params: { slug: ['my', 'path', '2'] } }] + + // We'll pre-render these paths at build time. + // { fallback: true } means other routes will be rendered at runtime. + return { paths, fallback: true } +} + +export async function getStaticProps({ params }) { + // The ID to render + const { slug } = params + const id = slug[slug.length - 1] + + const res = await fetch(`https://api.tvmaze.com/shows/${id}`) + const data = await res.json() + + return { + props: { + show: data, + }, + } +} + +export default Show diff --git a/demo/pages/getStaticProps/withFallback/[id].js b/demo/pages/getStaticProps/withFallback/[id].js new file mode 100644 index 0000000000..e872db34bf --- /dev/null +++ b/demo/pages/getStaticProps/withFallback/[id].js @@ -0,0 +1,54 @@ +import { useRouter } from 'next/router' +import Link from 'next/link' + +const Show = ({ show }) => { + const router = useRouter() + + // This is never shown on Netlify. We just need it for NextJS to be happy, + // because NextJS will render a fallback HTML page. + if (router.isFallback) { + return
Loading...
+ } + + return ( +
+

This page uses getStaticProps() to pre-fetch a TV show.

+ +
+ +

Show #{show.id}

+

{show.name}

+ +
+ + + Go back home + +
+ ) +} + +export async function getStaticPaths() { + // Set the paths we want to pre-render + const paths = [{ params: { id: '3' } }, { params: { id: '4' } }] + + // We'll pre-render these paths at build time. + // { fallback: true } means other routes will be rendered at runtime. + return { paths, fallback: true } +} + +export async function getStaticProps({ params }) { + // The ID to render + const { id } = params + + const res = await fetch(`https://api.tvmaze.com/shows/${id}`) + const data = await res.json() + + return { + props: { + show: data, + }, + } +} + +export default Show diff --git a/demo/pages/getStaticProps/withFallbackBlocking/[id].js b/demo/pages/getStaticProps/withFallbackBlocking/[id].js new file mode 100644 index 0000000000..1cefa83122 --- /dev/null +++ b/demo/pages/getStaticProps/withFallbackBlocking/[id].js @@ -0,0 +1,55 @@ +import { useRouter } from 'next/router' +import Link from 'next/link' + +const Show = ({ show }) => { + const router = useRouter() + + // This is never shown on Netlify. We just need it for NextJS to be happy, + // because NextJS will render a fallback HTML page. + if (router.isFallback) { + return
Loading...
+ } + + return ( +
+

This page uses getStaticProps() to pre-fetch a TV show.

+ +
+ +

Show #{show.id}

+

{show.name}

+ +
+ + + Go back home + +
+ ) +} + +export async function getStaticPaths() { + // Set the paths we want to pre-render + const paths = [{ params: { id: '3' } }, { params: { id: '4' } }] + + // We'll pre-render these paths at build time. + // { fallback: blocking } means routes will be built when visited for the + // first time and only after it's built will the client receive a response + return { paths, fallback: 'blocking' } +} + +export async function getStaticProps({ params }) { + // The ID to render + const { id } = params + + const res = await fetch(`https://api.tvmaze.com/shows/${id}`) + const data = await res.json() + + return { + props: { + show: data, + }, + } +} + +export default Show diff --git a/demo/pages/getStaticProps/withRevalidate/[id].js b/demo/pages/getStaticProps/withRevalidate/[id].js new file mode 100644 index 0000000000..7bf51a7933 --- /dev/null +++ b/demo/pages/getStaticProps/withRevalidate/[id].js @@ -0,0 +1,44 @@ +import Link from 'next/link' + +const Show = ({ show }) => ( +
+

This page uses getStaticProps() to pre-fetch a TV show.

+ +
+ +

Show #{show.id}

+

{show.name}

+ +
+ + + Go back home + +
+) + +export async function getStaticPaths() { + // Set the paths we want to pre-render + const paths = [{ params: { id: '1' } }, { params: { id: '2' } }] + + // 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 }) { + // The ID to render + const { id } = params + + const res = await fetch(`https://api.tvmaze.com/shows/${id}`) + const data = await res.json() + + return { + props: { + show: data, + }, + revalidate: 1, + } +} + +export default Show diff --git a/demo/pages/getStaticProps/withRevalidate/withFallback/[id].js b/demo/pages/getStaticProps/withRevalidate/withFallback/[id].js new file mode 100644 index 0000000000..5fb2522ef7 --- /dev/null +++ b/demo/pages/getStaticProps/withRevalidate/withFallback/[id].js @@ -0,0 +1,44 @@ +import Link from 'next/link' + +const Show = ({ show }) => ( +
+

This page uses getStaticProps() to pre-fetch a TV show.

+ +
+ +

Show #{show?.id}

+

{show?.name}

+ +
+ + + Go back home + +
+) + +export async function getStaticPaths() { + // Set the paths we want to pre-render + const paths = [{ params: { id: '1' } }, { params: { id: '2' } }] + + // We'll pre-render only these paths at build time. + // { fallback: false } means other routes should 404. + return { paths, fallback: true } +} + +export async function getStaticProps({ params }) { + // The ID to render + const { id } = params + + const res = await fetch(`https://api.tvmaze.com/shows/${id}`) + const data = await res.json() + + return { + props: { + show: data, + }, + revalidate: 1, + } +} + +export default Show diff --git a/demo/pages/index.js b/demo/pages/index.js new file mode 100644 index 0000000000..a62d6f99c9 --- /dev/null +++ b/demo/pages/index.js @@ -0,0 +1,127 @@ +import Link from 'next/link' + +const Index = ({ shows }) => ( +
+ NextJS on Netlify Banner + +

NextJS on Netlify

+

+ This is a demo of a NextJS application with Server-Side Rendering (SSR). +
+ It is hosted on Netlify. +
+ Server-side rendering is handled by Netlify Functions. +
+ Minimal configuration is required. +
+ Everything is handled by the next-on-netlify 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. +

+ + + +

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). +

+ + + +

3. Catch-All Routes? Included ✔

+

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

+ + +

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. +

+ + + +

Want to Learn More?

+

+ Check out the source code on GitHub. +

+
+) + +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/demo/pages/shows/[...params].js b/demo/pages/shows/[...params].js new file mode 100644 index 0000000000..c5a59b0da3 --- /dev/null +++ b/demo/pages/shows/[...params].js @@ -0,0 +1,61 @@ +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/demo/pages/shows/[id].js b/demo/pages/shows/[id].js new file mode 100644 index 0000000000..43ecafd3e5 --- /dev/null +++ b/demo/pages/shows/[id].js @@ -0,0 +1,49 @@ +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/demo/pages/static.js b/demo/pages/static.js new file mode 100644 index 0000000000..a063432ae9 --- /dev/null +++ b/demo/pages/static.js @@ -0,0 +1,26 @@ +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/demo/pages/static/[id].js b/demo/pages/static/[id].js new file mode 100644 index 0000000000..cc70b3136e --- /dev/null +++ b/demo/pages/static/[id].js @@ -0,0 +1,32 @@ +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/demo/public/favicon.ico b/demo/public/favicon.ico new file mode 100644 index 0000000000..4965832f2c Binary files /dev/null and b/demo/public/favicon.ico differ diff --git a/demo/styles/Home.module.css b/demo/styles/Home.module.css new file mode 100644 index 0000000000..35454bb748 --- /dev/null +++ b/demo/styles/Home.module.css @@ -0,0 +1,121 @@ +.container { + min-height: 100vh; + padding: 0 0.5rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100vh; +} + +.main { + padding: 5rem 0; + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.footer { + width: 100%; + height: 100px; + border-top: 1px solid #eaeaea; + display: flex; + justify-content: center; + align-items: center; +} + +.footer a { + display: flex; + justify-content: center; + align-items: center; + flex-grow: 1; +} + +.title a { + color: #0070f3; + text-decoration: none; +} + +.title a:hover, +.title a:focus, +.title a:active { + text-decoration: underline; +} + +.title { + margin: 0; + line-height: 1.15; + font-size: 4rem; +} + +.title, +.description { + text-align: center; +} + +.description { + line-height: 1.5; + font-size: 1.5rem; +} + +.code { + background: #fafafa; + border-radius: 5px; + padding: 0.75rem; + font-size: 1.1rem; + font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, + Bitstream Vera Sans Mono, Courier New, monospace; +} + +.grid { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + max-width: 800px; + margin-top: 3rem; +} + +.card { + margin: 1rem; + padding: 1.5rem; + text-align: left; + color: inherit; + text-decoration: none; + border: 1px solid #eaeaea; + border-radius: 10px; + transition: color 0.15s ease, border-color 0.15s ease; + width: 45%; +} + +.card:hover, +.card:focus, +.card:active { + color: #0070f3; + border-color: #0070f3; +} + +.card h2 { + margin: 0 0 1rem 0; + font-size: 1.5rem; +} + +.card p { + margin: 0; + font-size: 1.25rem; + line-height: 1.5; +} + +.logo { + height: 1em; + margin-left: 0.5rem; +} + +@media (max-width: 600px) { + .grid { + width: 100%; + flex-direction: column; + } +} diff --git a/demo/styles/globals.css b/demo/styles/globals.css new file mode 100644 index 0000000000..e5e2dcc23b --- /dev/null +++ b/demo/styles/globals.css @@ -0,0 +1,16 @@ +html, +body { + padding: 0; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; +} + +a { + color: inherit; + text-decoration: none; +} + +* { + box-sizing: border-box; +} diff --git a/index.js b/index.js index 8039d44938..510e62384e 100644 --- a/index.js +++ b/index.js @@ -10,7 +10,7 @@ const copyUnstableIncludedDirs = require('./helpers/copyUnstableIncludedDirs') const doesNotNeedPlugin = require('./helpers/doesNotNeedPlugin') const getNextConfig = require('./helpers/getNextConfig') const validateNextUsage = require('./helpers/validateNextUsage') -const nextOnNetlify = require('./src/index.js') +const nextOnNetlify = require('./src') const pWriteFile = util.promisify(fs.writeFile) diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 0000000000..d416a81896 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,2 @@ +[build] +base="demo/"