diff --git a/examples/blog-starter/now.json b/examples/blog-starter/now.json index e9ab941a260121..e2a1eb024cd292 100644 --- a/examples/blog-starter/now.json +++ b/examples/blog-starter/now.json @@ -1,8 +1,6 @@ { - "version": 2, "name": "nextjs-blog-starter", "alias": ["nextjs-blog-starter.now.sh"], - "builds": [{ "src": "package.json", "use": "@now/next" }], "routes": [ { "src": "/feed.json", "dest": "/_next/static/feed.json" }, { "src": "/blog/(?[^/]+)$", "dest": "/blog?page=$page" } diff --git a/examples/with-apollo/lib/apollo.js b/examples/with-apollo/lib/apollo.js index 54e4e3b8c8a4c2..61721bbf2d2117 100644 --- a/examples/with-apollo/lib/apollo.js +++ b/examples/with-apollo/lib/apollo.js @@ -1,4 +1,5 @@ import React from 'react' +import App from 'next/app' import Head from 'next/head' import { ApolloProvider } from '@apollo/react-hooks' import { ApolloClient } from 'apollo-client' @@ -12,11 +13,8 @@ let globalApolloClient = null * Creates and provides the apolloContext * to a next.js PageTree. Use it by wrapping * your PageComponent via HOC pattern. - * @param {Function|Class} PageComponent - * @param {Object} [config] - * @param {Boolean} [config.ssr=true] */ -export function withApollo(PageComponent, { ssr = true } = {}) { +export const withApollo = ({ ssr = true } = {}) => PageComponent => { const WithApollo = ({ apolloClient, apolloState, ...pageProps }) => { const client = apolloClient || initApolloClient(apolloState) return ( @@ -31,25 +29,44 @@ export function withApollo(PageComponent, { ssr = true } = {}) { const displayName = PageComponent.displayName || PageComponent.name || 'Component' - if (displayName === 'App') { - console.warn('This withApollo HOC only works with PageComponents.') - } - WithApollo.displayName = `withApollo(${displayName})` } if (ssr || PageComponent.getInitialProps) { WithApollo.getInitialProps = async ctx => { const { AppTree } = ctx + const inAppContext = Boolean(ctx.ctx) + + if (process.env.NODE_ENV === 'development') { + if (inAppContext) { + console.warn( + 'Warning: You have opted-out of Automatic Static Optimization due to `withApollo` in `pages/_app`.\n' + + 'Read more: https://err.sh/next.js/opt-out-auto-static-optimization\n' + ) + } + } - // Initialize ApolloClient, add it to the ctx object so - // we can use it in `PageComponent.getInitialProp`. - const apolloClient = (ctx.apolloClient = initApolloClient()) + if (ctx.apolloClient) { + throw new Error('Multiple instances of withApollo found.') + } + + // Initialize ApolloClient + const apolloClient = initApolloClient() + + // Add apolloClient to NextPageContext & NextAppContext + // This allows us to consume the apolloClient inside our + // custom `getInitialProps({ apolloClient })`. + ctx.apolloClient = apolloClient + if (inAppContext) { + ctx.ctx.apolloClient = apolloClient + } // Run wrapped getInitialProps methods let pageProps = {} if (PageComponent.getInitialProps) { pageProps = await PageComponent.getInitialProps(ctx) + } else if (inAppContext) { + pageProps = await App.getInitialProps(ctx) } // Only on the server: @@ -65,14 +82,19 @@ export function withApollo(PageComponent, { ssr = true } = {}) { try { // Run all GraphQL queries const { getDataFromTree } = await import('@apollo/react-ssr') - await getDataFromTree( - - ) + + // Since AppComponents and PageComponents have different context types + // we need to modify their props a little. + let props + if (inAppContext) { + props = { ...pageProps, apolloClient } + } else { + props = { pageProps: { ...pageProps, apolloClient } } + } + + // Takes React AppTree, determine which queries are needed to render, + // then fetche them all. + await getDataFromTree() } catch (error) { // Prevent Apollo Client GraphQL errors from crashing SSR. // Handle them in components via the data.error prop: @@ -104,7 +126,7 @@ export function withApollo(PageComponent, { ssr = true } = {}) { * Creates or reuses apollo client in the browser. * @param {Object} initialState */ -function initApolloClient(initialState) { +const initApolloClient = initialState => { // Make sure to create a new client for every server-side request so that data // isn't shared between connections (which would be bad) if (typeof window === 'undefined') { @@ -123,7 +145,7 @@ function initApolloClient(initialState) { * Creates and configures the ApolloClient * @param {Object} [initialState={}] */ -function createApolloClient(initialState = {}) { +const createApolloClient = (initialState = {}) => { // Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient return new ApolloClient({ ssrMode: typeof window === 'undefined', // Disables forceFetch on the server (so queries are only run once) diff --git a/examples/with-apollo/pages/client-only.js b/examples/with-apollo/pages/client-only.js index 1866c0941bf525..7fa37e3ca22b52 100644 --- a/examples/with-apollo/pages/client-only.js +++ b/examples/with-apollo/pages/client-only.js @@ -26,7 +26,5 @@ const ClientOnlyPage = props => ( ) -export default withApollo(ClientOnlyPage, { - // Disable apollo ssr fetching in favour of automatic static optimization - ssr: false, -}) +// Disable apollo ssr fetching in favour of automatic static optimization +export default withApollo({ ssr: false })(ClientOnlyPage) diff --git a/examples/with-apollo/pages/index.js b/examples/with-apollo/pages/index.js index fd7361809593d7..d40059d1a4620c 100644 --- a/examples/with-apollo/pages/index.js +++ b/examples/with-apollo/pages/index.js @@ -26,4 +26,4 @@ const IndexPage = props => ( ) -export default withApollo(IndexPage) +export default withApollo()(IndexPage) diff --git a/examples/with-now-env/now.json b/examples/with-now-env/now.json index f04eefdb3c0629..1305f0d9a0d26f 100644 --- a/examples/with-now-env/now.json +++ b/examples/with-now-env/now.json @@ -1,11 +1,4 @@ { - "version": 2, - "builds": [ - { - "src": "package.json", - "use": "@now/next" - } - ], "build": { "env": { "SECRET": "@my-secret-key", diff --git a/examples/with-stencil/README.md b/examples/with-stencil/README.md index ac2b873e51736b..ae0be530006721 100644 --- a/examples/with-stencil/README.md +++ b/examples/with-stencil/README.md @@ -47,6 +47,8 @@ Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit. now ``` +> Choose `packages/web-app` as root directory when deploying. + ## The idea behind the example Stencil is a compiler that generates Web Components (more specifically, Custom Elements). Stencil combines the best concepts of the most popular frameworks into a simple build-time tool. diff --git a/examples/with-stencil/now.json b/examples/with-stencil/now.json deleted file mode 100644 index 985a1b01d4007e..00000000000000 --- a/examples/with-stencil/now.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "version": 2, - "builds": [{ "src": "packages/web-app/package.json", "use": "@now/next" }], - "routes": [{ "src": "(.*)", "dest": "packages/web-app$1", "continue": true }] -} diff --git a/examples/with-three-js/README.md b/examples/with-three-js/README.md new file mode 100644 index 00000000000000..7e3ee2cff477ba --- /dev/null +++ b/examples/with-three-js/README.md @@ -0,0 +1,49 @@ +# With Three js + +This example uses: + +`threejs`: A lightweight, 3D library with a default WebGL renderer. The library also provides Canvas 2D, SVG and CSS3D renderers in the examples. +`react-three-fiber`: A React renderer for Threejs on the web and react-native. + +## Deploy your own + +Deploy the example using [ZEIT Now](https://zeit.co/now): + +[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/next.js/tree/canary/examples/with-three-js) + +## How to use + +### Using `create-next-app` + +Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: + +```bash +npx create-next-app --example with-three-js +# or +yarn create next-app --example with-three-js +``` + +### Download manually + +Download the example: + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-three-js +cd with-three-js +``` + +Install it and run: + +```bash +npm install +npm run dev +# or +yarn +yarn dev +``` + +Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)): + +```bash +now +``` diff --git a/examples/with-three-js/package.json b/examples/with-three-js/package.json new file mode 100644 index 00000000000000..faa0204c782706 --- /dev/null +++ b/examples/with-three-js/package.json @@ -0,0 +1,18 @@ +{ + "name": "with-three-js", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "9.2.1", + "react": "16.12.0", + "react-dom": "16.12.0", + "react-three-fiber": "4.0.12", + "three": "0.112.1" + }, + "devDependencies": {} +} diff --git a/examples/with-three-js/pages/_app.js b/examples/with-three-js/pages/_app.js new file mode 100644 index 00000000000000..a0549e5c10ac7f --- /dev/null +++ b/examples/with-three-js/pages/_app.js @@ -0,0 +1,8 @@ +import React from 'react' +import './index.css' + +function MyApp({ Component, pageProps }) { + return +} + +export default MyApp diff --git a/examples/with-three-js/pages/birds.js b/examples/with-three-js/pages/birds.js new file mode 100644 index 00000000000000..f9b2d4a042f068 --- /dev/null +++ b/examples/with-three-js/pages/birds.js @@ -0,0 +1,84 @@ +import React, { useRef, useState, useEffect, Suspense } from 'react' +import * as THREE from 'three' +import { Canvas, useFrame, useLoader } from 'react-three-fiber' + +let GLTFLoader + +const Bird = ({ speed, factor, url, ...props }) => { + const gltf = useLoader(GLTFLoader, url) + const group = useRef() + const [mixer] = useState(() => new THREE.AnimationMixer()) + useEffect( + () => void mixer.clipAction(gltf.animations[0], group.current).play(), + [gltf.animations, mixer] + ) + useFrame((state, delta) => { + group.current.rotation.y += + Math.sin((delta * factor) / 2) * Math.cos((delta * factor) / 2) * 1.5 + mixer.update(delta * speed) + }) + return ( + + + + + + + + + ) +} + +const Birds = () => { + return new Array(5).fill().map((_, i) => { + const x = (15 + Math.random() * 30) * (Math.round(Math.random()) ? -1 : 1) + const y = -10 + Math.random() * 20 + const z = -5 + Math.random() * 10 + const bird = ['stork', 'parrot', 'flamingo'][Math.round(Math.random() * 2)] + let speed = bird === 'stork' ? 0.5 : bird === 'flamingo' ? 2 : 5 + let factor = + bird === 'stork' + ? 0.5 + Math.random() + : bird === 'flamingo' + ? 0.25 + Math.random() + : 1 + Math.random() - 0.5 + return ( + 0 ? Math.PI : 0, 0]} + speed={speed} + factor={factor} + url={`/glb/${bird}.glb`} + /> + ) + }) +} + +const BirdsPage = props => { + useEffect(() => { + GLTFLoader = require('three/examples/jsm/loaders/GLTFLoader').GLTFLoader + }, []) + return ( + <> + + + + + + + + + ) +} + +export default BirdsPage diff --git a/examples/with-three-js/pages/boxes.js b/examples/with-three-js/pages/boxes.js new file mode 100644 index 00000000000000..8fba862a743fbb --- /dev/null +++ b/examples/with-three-js/pages/boxes.js @@ -0,0 +1,46 @@ +import React, { useRef, useState, Suspense } from 'react' +import { Canvas, useFrame } from 'react-three-fiber' + +const Box = props => { + const mesh = useRef() + + const [hovered, setHover] = useState(false) + const [active, setActive] = useState(false) + + useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01)) + + return ( + setActive(!active)} + onPointerOver={e => setHover(true)} + onPointerOut={e => setHover(false)} + > + + + + ) +} + +const BirdsPage = () => { + return [ +

Click on me - Hover me :)

, + + + + + + + + + + , + ] +} + +export default BirdsPage diff --git a/examples/with-three-js/pages/index.css b/examples/with-three-js/pages/index.css new file mode 100644 index 00000000000000..5099ed4a8a60b4 --- /dev/null +++ b/examples/with-three-js/pages/index.css @@ -0,0 +1,43 @@ +body { + margin: 0; + padding: 0; + width: 100%; + height: 100vh; + background: lavender; +} + +canvas { + width: 100%; + height: 100vh; +} + +h1 { + display: flex; + justify-content: center; + align-content: center; + color: hotpink; +} + +.main { + background: hotpink; + padding: 50px; + border-radius: 4px; + display: flex; + margin: 200px; + flex-direction: column; + justify-content: center; + align-items: center; + color: white; +} + +a { + color: white; + display: block; + text-decoration: unset; + font-size: 20px; + margin: 5px 0; +} + +a:hover { + color: #3f51b5; +} diff --git a/examples/with-three-js/pages/index.js b/examples/with-three-js/pages/index.js new file mode 100644 index 00000000000000..7164e9d7f28bcf --- /dev/null +++ b/examples/with-three-js/pages/index.js @@ -0,0 +1,17 @@ +import React from 'react' +import Link from 'next/link' + +const Index = () => { + return ( + + ) +} + +export default Index diff --git a/examples/with-three-js/public/glb/flamingo.glb b/examples/with-three-js/public/glb/flamingo.glb new file mode 100644 index 00000000000000..2135fc0f736843 Binary files /dev/null and b/examples/with-three-js/public/glb/flamingo.glb differ diff --git a/examples/with-three-js/public/glb/parrot.glb b/examples/with-three-js/public/glb/parrot.glb new file mode 100644 index 00000000000000..2ea9e583118531 Binary files /dev/null and b/examples/with-three-js/public/glb/parrot.glb differ diff --git a/examples/with-three-js/public/glb/stork.glb b/examples/with-three-js/public/glb/stork.glb new file mode 100644 index 00000000000000..1358255157b52c Binary files /dev/null and b/examples/with-three-js/public/glb/stork.glb differ diff --git a/examples/with-yarn-workspaces/README.md b/examples/with-yarn-workspaces/README.md index 15e1d756fbb0cb..c77eba540103d7 100644 --- a/examples/with-yarn-workspaces/README.md +++ b/examples/with-yarn-workspaces/README.md @@ -48,6 +48,8 @@ Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit. now ``` +> Choose `packages/web-app` as root directory when deploying. + ## Useful Links - [Documentation](https://yarnpkg.com/en/docs/workspaces) diff --git a/examples/with-yarn-workspaces/now.json b/examples/with-yarn-workspaces/now.json deleted file mode 100644 index 985a1b01d4007e..00000000000000 --- a/examples/with-yarn-workspaces/now.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "version": 2, - "builds": [{ "src": "packages/web-app/package.json", "use": "@now/next" }], - "routes": [{ "src": "(.*)", "dest": "packages/web-app$1", "continue": true }] -} diff --git a/examples/with-zones/README.md b/examples/with-zones/README.md index 4eb263d57c88d5..a10e282471baa6 100644 --- a/examples/with-zones/README.md +++ b/examples/with-zones/README.md @@ -31,21 +31,15 @@ cd with-zones ## Notes -In this example, we have two apps: 'home' and 'blog'. We'll start both apps with [Now](https://zeit.co/now): - -```bash -now dev -``` - -Then, you can visit and develop for both apps as a single app. - -You can also start the apps separately, for example: +In this example, we have two apps: 'home' and 'blog'. You can start each app separately, for example: ```bash cd blog yarn dev ``` +Then, you can visit and develop your app. + ## Special Notes - All pages should be unique across zones. For example, the 'home' app should not have a `pages/blog/index.js` page. @@ -55,8 +49,11 @@ yarn dev ## Production Deployment -We only need to run `now`, the same `now.json` used for development will be used for the deployment: +We only need to run `now `, to deploy the app: ```bash -now +now blog +now home ``` + +> The rewrite destination in your `now.json` file in the `home` app must be adjusted to point to your deployment. diff --git a/examples/with-zones/blog/.gitignore b/examples/with-zones/blog/.gitignore index f74c78183c9179..e54e38fa532b36 100644 --- a/examples/with-zones/blog/.gitignore +++ b/examples/with-zones/blog/.gitignore @@ -1,2 +1,4 @@ .next node_modules + +.now \ No newline at end of file diff --git a/examples/with-zones/blog/now.json b/examples/with-zones/blog/now.json new file mode 100644 index 00000000000000..9dcd887d881d87 --- /dev/null +++ b/examples/with-zones/blog/now.json @@ -0,0 +1,13 @@ +{ + "build": { + "env": { + "BUILDING_FOR_NOW": "true" + } + }, + "rewrites": [ + { + "source": "/blog/_next$1", + "destination": "/_next$1" + } + ] +} diff --git a/examples/with-zones/home/.gitignore b/examples/with-zones/home/.gitignore index f74c78183c9179..e54e38fa532b36 100644 --- a/examples/with-zones/home/.gitignore +++ b/examples/with-zones/home/.gitignore @@ -1,2 +1,4 @@ .next node_modules + +.now \ No newline at end of file diff --git a/examples/with-zones/home/now.json b/examples/with-zones/home/now.json new file mode 100644 index 00000000000000..7981357aa4e9b8 --- /dev/null +++ b/examples/with-zones/home/now.json @@ -0,0 +1,8 @@ +{ + "rewrites": [ + { + "source": "/blog(.*)", + "destination": "https://with-zones-blog.now.sh$1" + } + ] +} diff --git a/examples/with-zones/now.json b/examples/with-zones/now.json deleted file mode 100644 index 590167dd6c7ab6..00000000000000 --- a/examples/with-zones/now.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "with-zones", - "version": 2, - "builds": [ - { "src": "blog/next.config.js", "use": "@now/next" }, - { "src": "home/next.config.js", "use": "@now/next" } - ], - "routes": [ - { "src": "/blog/(_next|static)(.*)" }, - { "src": "/blog(.*)", "dest": "blog/blog$1", "continue": true }, - { "src": "(?!/?blog)(.*)", "dest": "home$1", "continue": true } - ], - "build": { - "env": { - "BUILDING_FOR_NOW": "true" - } - } -} diff --git a/examples/z-experimental-next-news/now.json b/examples/z-experimental-next-news/now.json deleted file mode 100644 index 404c3ff46d5d78..00000000000000 --- a/examples/z-experimental-next-news/now.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "builds": [{ "src": "package.json", "use": "@now/next@canary" }] -} diff --git a/lerna.json b/lerna.json index b1028ed5beef44..73975b59fa355a 100644 --- a/lerna.json +++ b/lerna.json @@ -12,5 +12,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "9.2.2-canary.9" + "version": "9.2.2-canary.14" } diff --git a/package.json b/package.json index 18a27400823189..f5bf15c7eb34c6 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@babel/preset-react": "7.7.0", "@fullhuman/postcss-purgecss": "1.3.0", "@mdx-js/loader": "0.18.0", + "@types/http-proxy": "1.17.3", "@types/jest": "24.0.13", "@types/string-hash": "1.1.1", "@typescript-eslint/eslint-plugin": "2.17.0", @@ -53,7 +54,9 @@ "babel-core": "7.0.0-bridge.0", "babel-eslint": "10.0.3", "babel-jest": "24.9.0", + "browserslist": "^4.8.3", "browserstack-local": "1.4.0", + "caniuse-lite": "^1.0.30001019", "cheerio": "0.22.0", "clone": "2.1.2", "coveralls": "3.0.3", @@ -100,9 +103,7 @@ "tree-kill": "1.2.1", "typescript": "3.7.3", "wait-port": "0.2.2", - "webpack-bundle-analyzer": "3.3.2", - "browserslist": "^4.8.3", - "caniuse-lite": "^1.0.30001019" + "webpack-bundle-analyzer": "3.3.2" }, "resolutions": { "browserslist": "^4.8.3", diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 875bc1f8fb9e04..63659673eed808 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "9.2.2-canary.9", + "version": "9.2.2-canary.14", "keywords": [ "react", "next", diff --git a/packages/create-next-app/templates/default/README.md b/packages/create-next-app/templates/default/README.md index bdfa3f51f0d208..007329cc4b829a 100644 --- a/packages/create-next-app/templates/default/README.md +++ b/packages/create-next-app/templates/default/README.md @@ -152,7 +152,7 @@ To configure the syntax highlighting in your favorite text editor, head to the [ ## Deploy to Now -[ZEIT Now](https://zeit.co/home?utm_source=create-next-app&utm_medium=referral&utm_campaign=Create%20Next%20App) offers a zero-configuration single-command deployment. +[ZEIT Now](https://zeit.co/home?utm_source=create-next-app&utm_medium=readme&utm_campaign=create-next-app) offers a zero-configuration single-command deployment. 1. Install the `now` command-line tool either via npm `npm install -g now` or Yarn `yarn global add now`. @@ -164,7 +164,7 @@ To configure the syntax highlighting in your favorite text editor, head to the [ Paste that URL into your browser when the build is complete, and you will see your deployed app. -You can find more details about [`ZEIT Now` here](https://zeit.co/home?utm_source=create-next-app&utm_medium=referral&utm_campaign=Create%20Next%20App). +You can find more details about [`ZEIT Now` here](https://zeit.co/home?utm_source=create-next-app&utm_medium=readme&utm_campaign=create-next-app). ## Something Missing? diff --git a/packages/create-next-app/templates/default/pages/index.js b/packages/create-next-app/templates/default/pages/index.js index 871b2b26f22b32..7310dd0dddf5d1 100644 --- a/packages/create-next-app/templates/default/pages/index.js +++ b/packages/create-next-app/templates/default/pages/index.js @@ -37,7 +37,7 @@ const Home = () => (

Deploy →

@@ -50,7 +50,7 @@ const Home = () => (