diff --git a/.babelrc b/.babelrc index 900da0c0..2f687fa0 100644 --- a/.babelrc +++ b/.babelrc @@ -1,7 +1,8 @@ { "presets": [ "env", - "react" + "react", + "flow" ], "plugins": [ "transform-object-rest-spread", diff --git a/.flowconfig b/.flowconfig new file mode 100644 index 00000000..581592b1 --- /dev/null +++ b/.flowconfig @@ -0,0 +1,2 @@ +[ignore] +/examples/.* \ No newline at end of file diff --git a/bin/next-build b/bin/next-build index c9cab029..5261802f 100755 --- a/bin/next-build +++ b/bin/next-build @@ -43,7 +43,7 @@ if (!existsSync(join(dir, 'pages'))) { } build(dir) -.catch((err) => { - console.error(err) - process.exit(1) -}) + .catch((err) => { + console.error(err) + process.exit(1) + }) diff --git a/bin/next-dev b/bin/next-dev index dc1693b0..2a3c8f6c 100755 --- a/bin/next-dev +++ b/bin/next-dev @@ -54,23 +54,23 @@ if (!existsSync(join(dir, 'pages'))) { const srv = new Server({ dir, dev: true }) srv.start(argv.port, argv.hostname) -.then(async () => { - if (!process.env.NOW) { - console.log(`> Ready on http://${argv.hostname ? argv.hostname : 'localhost'}:${argv.port}`) - } -}) -.catch((err) => { - if (err.code === 'EADDRINUSE') { - let errorMessage = `Port ${argv.port} is already in use.` - const pkgAppPath = require('find-up').sync('package.json', { - cwd: dir - }) - const appPackage = JSON.parse(readFileSync(pkgAppPath, 'utf8')) - const nextScript = Object.entries(appPackage.scripts).find(scriptLine => scriptLine[1] === 'next') - if (nextScript) errorMessage += `\nUse \`npm run ${nextScript[0]} -- -p \`.` - console.error(errorMessage) - } else { - console.error(err) - } - process.nextTick(() => process.exit(1)) -}) + .then(async () => { + if (!process.env.NOW) { + console.log(`> Ready on http://${argv.hostname ? argv.hostname : 'localhost'}:${argv.port}`) + } + }) + .catch((err) => { + if (err.code === 'EADDRINUSE') { + let errorMessage = `Port ${argv.port} is already in use.` + const pkgAppPath = require('find-up').sync('package.json', { + cwd: dir + }) + const appPackage = JSON.parse(readFileSync(pkgAppPath, 'utf8')) + const nextScript = Object.entries(appPackage.scripts).find(scriptLine => scriptLine[1] === 'next') + if (nextScript) errorMessage += `\nUse \`npm run ${nextScript[0]} -- -p \`.` + console.error(errorMessage) + } else { + console.error(err) + } + process.nextTick(() => process.exit(1)) + }) diff --git a/bin/next-start b/bin/next-start index fd743e3b..19832a17 100755 --- a/bin/next-start +++ b/bin/next-start @@ -46,12 +46,12 @@ const dir = resolve(argv._[0] || '.') const srv = new Server({ dir }) srv.start(argv.port, argv.hostname) -.then(() => { - if (!process.env.NOW) { - console.log(`> Ready on http://${argv.hostname ? argv.hostname : 'localhost'}:${argv.port}`) - } -}) -.catch((err) => { - console.error(err) - process.exit(1) -}) + .then(() => { + if (!process.env.NOW) { + console.log(`> Ready on http://${argv.hostname ? argv.hostname : 'localhost'}:${argv.port}`) + } + }) + .catch((err) => { + console.error(err) + process.exit(1) + }) diff --git a/examples/custom-charset/server.js b/examples/custom-charset/server.js index bf8b0a43..5cc46fb4 100644 --- a/examples/custom-charset/server.js +++ b/examples/custom-charset/server.js @@ -8,14 +8,14 @@ const app = next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - createServer((req, res) => { - const parsedUrl = parse(req.url, true) - res.setHeader('Content-Type', 'text/html; charset=iso-8859-2') - handle(req, res, parsedUrl) + .then(() => { + createServer((req, res) => { + const parsedUrl = parse(req.url, true) + res.setHeader('Content-Type', 'text/html; charset=iso-8859-2') + handle(req, res, parsedUrl) + }) + .listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) - .listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) - }) -}) diff --git a/examples/custom-server-actionhero/config/tasks.js b/examples/custom-server-actionhero/config/tasks.js index f32d4d42..b5652c2e 100644 --- a/examples/custom-server-actionhero/config/tasks.js +++ b/examples/custom-server-actionhero/config/tasks.js @@ -8,7 +8,7 @@ exports['default'] = { // Logging levels of task workers workerLogging: { failure: 'error', // task failure - success: 'info', // task success + success: 'info', // task success start: 'info', end: 'info', cleaning_worker: 'info', diff --git a/examples/custom-server-express/server.js b/examples/custom-server-express/server.js index 208bfe97..3a645a6c 100644 --- a/examples/custom-server-express/server.js +++ b/examples/custom-server-express/server.js @@ -7,27 +7,27 @@ const app = next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - const server = express() + .then(() => { + const server = express() - server.get('/a', (req, res) => { - return app.render(req, res, '/b', req.query) - }) + server.get('/a', (req, res) => { + return app.render(req, res, '/b', req.query) + }) - server.get('/b', (req, res) => { - return app.render(req, res, '/a', req.query) - }) + server.get('/b', (req, res) => { + return app.render(req, res, '/a', req.query) + }) - server.get('/posts/:id', (req, res) => { - return app.render(req, res, '/posts', { id: req.params.id }) - }) + server.get('/posts/:id', (req, res) => { + return app.render(req, res, '/posts', { id: req.params.id }) + }) - server.get('*', (req, res) => { - return handle(req, res) - }) + server.get('*', (req, res) => { + return handle(req, res) + }) - server.listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) + server.listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) -}) diff --git a/examples/custom-server-fastify/server.js b/examples/custom-server-fastify/server.js index 8c8fa8ce..910afac6 100644 --- a/examples/custom-server-fastify/server.js +++ b/examples/custom-server-fastify/server.js @@ -7,23 +7,23 @@ const app = Next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - const server = fastify() + .then(() => { + const server = fastify() - server.get('/a', (req, res) => { - return app.render(req.req, res.res, '/a', req.query) - }) + server.get('/a', (req, res) => { + return app.render(req.req, res.res, '/a', req.query) + }) - server.get('/b', (req, res) => { - return app.render(req.req, res.res, '/b', req.query) - }) + server.get('/b', (req, res) => { + return app.render(req.req, res.res, '/b', req.query) + }) - server.get('/*', (req, res) => { - return handle(req.req, res.res) - }) + server.get('/*', (req, res) => { + return handle(req.req, res.res) + }) - server.listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) + server.listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) -}) diff --git a/examples/custom-server-hapi/server.js b/examples/custom-server-hapi/server.js index d79e0cac..4019d0f9 100644 --- a/examples/custom-server-hapi/server.js +++ b/examples/custom-server-hapi/server.js @@ -10,37 +10,37 @@ const server = new Hapi.Server({ }) app -.prepare() -.then(async () => { - server.route({ - method: 'GET', - path: '/a', - handler: pathWrapper(app, '/a') - }) + .prepare() + .then(async () => { + server.route({ + method: 'GET', + path: '/a', + handler: pathWrapper(app, '/a') + }) - server.route({ - method: 'GET', - path: '/b', - handler: pathWrapper(app, '/b') - }) + server.route({ + method: 'GET', + path: '/b', + handler: pathWrapper(app, '/b') + }) - server.route({ - method: 'GET', - path: '/_next/{p*}', /* next specific routes */ - handler: nextHandlerWrapper(app) - }) + server.route({ + method: 'GET', + path: '/_next/{p*}', /* next specific routes */ + handler: nextHandlerWrapper(app) + }) - server.route({ - method: 'GET', - path: '/{p*}', /* catch all route */ - handler: defaultHandlerWrapper(app) - }) + server.route({ + method: 'GET', + path: '/{p*}', /* catch all route */ + handler: defaultHandlerWrapper(app) + }) - try { - await server.start() - console.log(`> Ready on http://localhost:${port}`) - } catch (error) { - console.log('Error starting server') - console.log(error) - } -}) + try { + await server.start() + console.log(`> Ready on http://localhost:${port}`) + } catch (error) { + console.log('Error starting server') + console.log(error) + } + }) diff --git a/examples/custom-server-koa/server.js b/examples/custom-server-koa/server.js index 532abeee..fb122444 100644 --- a/examples/custom-server-koa/server.js +++ b/examples/custom-server-koa/server.js @@ -8,32 +8,32 @@ const app = next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - const server = new Koa() - const router = new Router() + .then(() => { + const server = new Koa() + const router = new Router() - router.get('/a', async ctx => { - await app.render(ctx.req, ctx.res, '/b', ctx.query) - ctx.respond = false - }) + router.get('/a', async ctx => { + await app.render(ctx.req, ctx.res, '/b', ctx.query) + ctx.respond = false + }) - router.get('/b', async ctx => { - await app.render(ctx.req, ctx.res, '/a', ctx.query) - ctx.respond = false - }) + router.get('/b', async ctx => { + await app.render(ctx.req, ctx.res, '/a', ctx.query) + ctx.respond = false + }) - router.get('*', async ctx => { - await handle(ctx.req, ctx.res) - ctx.respond = false - }) + router.get('*', async ctx => { + await handle(ctx.req, ctx.res) + ctx.respond = false + }) - server.use(async (ctx, next) => { - ctx.res.statusCode = 200 - await next() - }) + server.use(async (ctx, next) => { + ctx.res.statusCode = 200 + await next() + }) - server.use(router.routes()) - server.listen(port, () => { - console.log(`> Ready on http://localhost:${port}`) + server.use(router.routes()) + server.listen(port, () => { + console.log(`> Ready on http://localhost:${port}`) + }) }) -}) diff --git a/examples/custom-server-nodemon/server/index.js b/examples/custom-server-nodemon/server/index.js index 56cda752..3684c62c 100644 --- a/examples/custom-server-nodemon/server/index.js +++ b/examples/custom-server-nodemon/server/index.js @@ -8,21 +8,21 @@ const app = next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - createServer((req, res) => { - const parsedUrl = parse(req.url, true) - const { pathname, query } = parsedUrl + .then(() => { + createServer((req, res) => { + const parsedUrl = parse(req.url, true) + const { pathname, query } = parsedUrl - if (pathname === '/a') { - app.render(req, res, '/b', query) - } else if (pathname === '/b') { - app.render(req, res, '/a', query) - } else { - handle(req, res, parsedUrl) - } + if (pathname === '/a') { + app.render(req, res, '/b', query) + } else if (pathname === '/b') { + app.render(req, res, '/a', query) + } else { + handle(req, res, parsedUrl) + } + }) + .listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) - .listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) - }) -}) diff --git a/examples/custom-server-typescript/package.json b/examples/custom-server-typescript/package.json index 11faa2f8..73d7869e 100644 --- a/examples/custom-server-typescript/package.json +++ b/examples/custom-server-typescript/package.json @@ -7,14 +7,14 @@ "dependencies": { "next": "latest", "react": "^16.2.0", - "react-dom": "^16.2.0" + "react-dom": "^16.2.0", + "@zeit/next-typescript": "0.0.11", + "typescript": "^2.7.1" }, "devDependencies": { "@types/next": "^2.4.7", "@types/react": "^16.0.36", - "@zeit/next-typescript": "^0.0.8", "nodemon": "^1.12.1", - "ts-node": "^4.1.0", - "typescript": "^2.7.1" + "ts-node": "^4.1.0" } } diff --git a/examples/custom-server/server.js b/examples/custom-server/server.js index 56cda752..3684c62c 100644 --- a/examples/custom-server/server.js +++ b/examples/custom-server/server.js @@ -8,21 +8,21 @@ const app = next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - createServer((req, res) => { - const parsedUrl = parse(req.url, true) - const { pathname, query } = parsedUrl + .then(() => { + createServer((req, res) => { + const parsedUrl = parse(req.url, true) + const { pathname, query } = parsedUrl - if (pathname === '/a') { - app.render(req, res, '/b', query) - } else if (pathname === '/b') { - app.render(req, res, '/a', query) - } else { - handle(req, res, parsedUrl) - } + if (pathname === '/a') { + app.render(req, res, '/b', query) + } else if (pathname === '/b') { + app.render(req, res, '/a', query) + } else { + handle(req, res, parsedUrl) + } + }) + .listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) - .listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) - }) -}) diff --git a/examples/form-handler/server.js b/examples/form-handler/server.js index 87c18710..46839ab0 100644 --- a/examples/form-handler/server.js +++ b/examples/form-handler/server.js @@ -6,23 +6,23 @@ const app = next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - const server = express() + .then(() => { + const server = express() - server.get('/', (req, res) => { - return handle(req, res) - }) + server.get('/', (req, res) => { + return handle(req, res) + }) - server.get('*', (req, res) => { - return handle(req, res) - }) + server.get('*', (req, res) => { + return handle(req, res) + }) - server.listen(3000, (err) => { - if (err) throw err - console.log('> Ready on http://localhost:3000') + server.listen(3000, (err) => { + if (err) throw err + console.log('> Ready on http://localhost:3000') + }) + }) + .catch((ex) => { + console.error(ex.stack) + process.exit(1) }) -}) -.catch((ex) => { - console.error(ex.stack) - process.exit(1) -}) diff --git a/examples/parameterized-routing/server.js b/examples/parameterized-routing/server.js index c0b1a329..74358d06 100644 --- a/examples/parameterized-routing/server.js +++ b/examples/parameterized-routing/server.js @@ -11,21 +11,21 @@ const route = pathMatch() const match = route('/blog/:id') app.prepare() -.then(() => { - createServer((req, res) => { - const { pathname, query } = parse(req.url, true) - const params = match(pathname) - if (params === false) { - handle(req, res) - return - } - // assigning `query` into the params means that we still - // get the query string passed to our application - // i.e. /blog/foo?show-comments=true - app.render(req, res, '/blog', Object.assign(params, query)) + .then(() => { + createServer((req, res) => { + const { pathname, query } = parse(req.url, true) + const params = match(pathname) + if (params === false) { + handle(req, res) + return + } + // assigning `query` into the params means that we still + // get the query string passed to our application + // i.e. /blog/foo?show-comments=true + app.render(req, res, '/blog', Object.assign(params, query)) + }) + .listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) - .listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) - }) -}) diff --git a/examples/root-static-files/server.js b/examples/root-static-files/server.js index 3b6c2166..74743aaa 100644 --- a/examples/root-static-files/server.js +++ b/examples/root-static-files/server.js @@ -9,23 +9,23 @@ const app = next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - createServer((req, res) => { - const parsedUrl = parse(req.url, true) - const rootStaticFiles = [ - '/robots.txt', - '/sitemap.xml', - '/favicon.ico' - ] - if (rootStaticFiles.indexOf(parsedUrl.pathname) > -1) { - const path = join(__dirname, 'static', parsedUrl.pathname) - app.serveStatic(req, res, path) - } else { - handle(req, res, parsedUrl) - } + .then(() => { + createServer((req, res) => { + const parsedUrl = parse(req.url, true) + const rootStaticFiles = [ + '/robots.txt', + '/sitemap.xml', + '/favicon.ico' + ] + if (rootStaticFiles.indexOf(parsedUrl.pathname) > -1) { + const path = join(__dirname, 'static', parsedUrl.pathname) + app.serveStatic(req, res, path) + } else { + handle(req, res, parsedUrl) + } + }) + .listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) - .listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) - }) -}) diff --git a/examples/ssr-caching/server.js b/examples/ssr-caching/server.js index 8f0ef4d8..e5cb715a 100644 --- a/examples/ssr-caching/server.js +++ b/examples/ssr-caching/server.js @@ -14,28 +14,28 @@ const ssrCache = new LRUCache({ }) app.prepare() -.then(() => { - const server = express() + .then(() => { + const server = express() - // Use the `renderAndCache` utility defined below to serve pages - server.get('/', (req, res) => { - renderAndCache(req, res, '/') - }) + // Use the `renderAndCache` utility defined below to serve pages + server.get('/', (req, res) => { + renderAndCache(req, res, '/') + }) - server.get('/blog/:id', (req, res) => { - const queryParams = { id: req.params.id } - renderAndCache(req, res, '/blog', queryParams) - }) + server.get('/blog/:id', (req, res) => { + const queryParams = { id: req.params.id } + renderAndCache(req, res, '/blog', queryParams) + }) - server.get('*', (req, res) => { - return handle(req, res) - }) + server.get('*', (req, res) => { + return handle(req, res) + }) - server.listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) + server.listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) -}) /* * NB: make sure to modify this to take into account anything that should trigger diff --git a/examples/using-inferno/server.js b/examples/using-inferno/server.js index 75750367..5a493bdb 100644 --- a/examples/using-inferno/server.js +++ b/examples/using-inferno/server.js @@ -18,13 +18,13 @@ const app = next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - createServer((req, res) => { - const parsedUrl = parse(req.url, true) - handle(req, res, parsedUrl) + .then(() => { + createServer((req, res) => { + const parsedUrl = parse(req.url, true) + handle(req, res, parsedUrl) + }) + .listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) - .listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) - }) -}) diff --git a/examples/using-nerv/server.js b/examples/using-nerv/server.js index e28d7afd..99bb3847 100644 --- a/examples/using-nerv/server.js +++ b/examples/using-nerv/server.js @@ -17,13 +17,13 @@ const app = next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - createServer((req, res) => { - const parsedUrl = parse(req.url, true) - handle(req, res, parsedUrl) + .then(() => { + createServer((req, res) => { + const parsedUrl = parse(req.url, true) + handle(req, res, parsedUrl) + }) + .listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) - .listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) - }) -}) diff --git a/examples/using-preact/server.js b/examples/using-preact/server.js index a0cefda4..3b516843 100644 --- a/examples/using-preact/server.js +++ b/examples/using-preact/server.js @@ -11,13 +11,13 @@ const app = next({ dev }) const handle = app.getRequestHandler() app.prepare() -.then(() => { - createServer((req, res) => { - const parsedUrl = parse(req.url, true) - handle(req, res, parsedUrl) + .then(() => { + createServer((req, res) => { + const parsedUrl = parse(req.url, true) + handle(req, res, parsedUrl) + }) + .listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) - .listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) - }) -}) diff --git a/examples/with-ant-design/next.config.js b/examples/with-ant-design/next.config.js index 7adc9659..19948b9c 100644 --- a/examples/with-ant-design/next.config.js +++ b/examples/with-ant-design/next.config.js @@ -1,3 +1,4 @@ +/* eslint-disable */ const withCss = require('@zeit/next-css') // fix: prevents error when .css files are required by node diff --git a/examples/with-apollo-and-redux-saga/README.md b/examples/with-apollo-and-redux-saga/README.md index 63f39083..226e29f6 100644 --- a/examples/with-apollo-and-redux-saga/README.md +++ b/examples/with-apollo-and-redux-saga/README.md @@ -49,3 +49,6 @@ export default withReduxSaga(connect(mapStateToProps, null)(Index)); ``` `connect` must go inside `withReduxSaga` otherwise `connect` will not be able to find the store. + +### Note: +In these *with-apollo* examples, the ```withData()``` HOC must wrap a top-level component from within the ```pages``` directory. Wrapping a child component with the HOC will result in a ```Warning: Failed prop type: The prop 'serverState' is marked as required in 'WithData(Apollo(Component))', but its value is 'undefined'``` error. Down-tree child components will have access to Apollo, and can be wrapped with any other sort of ```graphql()```, ```compose()```, etc HOC's. diff --git a/examples/with-apollo-and-redux/README.md b/examples/with-apollo-and-redux/README.md index 548a4556..5f3b1940 100644 --- a/examples/with-apollo-and-redux/README.md +++ b/examples/with-apollo-and-redux/README.md @@ -48,4 +48,7 @@ const mapStateToProps = state => ({ }); export default withRedux(connect(mapStateToProps, null)(Index)); -``` \ No newline at end of file +``` + +### Note: +In these *with-apollo* examples, the ```withData()``` HOC must wrap a top-level component from within the ```pages``` directory. Wrapping a child component with the HOC will result in a ```Warning: Failed prop type: The prop 'serverState' is marked as required in 'WithData(Apollo(Component))', but its value is 'undefined'``` error. Down-tree child components will have access to Apollo, and can be wrapped with any other sort of ```graphql()```, ```compose()```, etc HOC's. diff --git a/examples/with-apollo-auth/README.md b/examples/with-apollo-auth/README.md index ff14ceff..00482128 100644 --- a/examples/with-apollo-auth/README.md +++ b/examples/with-apollo-auth/README.md @@ -66,3 +66,7 @@ It is important to note the use of Apollo's `resetStore()` method after signing To get this example running locally, you will need to create a graph.cool account, and provide [the `project.graphcool` schema](https://github.com/zeit/next.js/blob/master/examples/with-apollo-auth/project.graphcool). + + +### Note: +In these *with-apollo* examples, the ```withData()``` HOC must wrap a top-level component from within the ```pages``` directory. Wrapping a child component with the HOC will result in a ```Warning: Failed prop type: The prop 'serverState' is marked as required in 'WithData(Apollo(Component))', but its value is 'undefined'``` error. Down-tree child components will have access to Apollo, and can be wrapped with any other sort of ```graphql()```, ```compose()```, etc HOC's. diff --git a/examples/with-apollo/README.md b/examples/with-apollo/README.md index 563485e8..feee245d 100644 --- a/examples/with-apollo/README.md +++ b/examples/with-apollo/README.md @@ -48,3 +48,6 @@ In this simple example, we integrate Apollo seamlessly with Next by wrapping our On initial page load, while on the server and inside `getInitialProps`, we invoke the Apollo method, [`getDataFromTree`](http://dev.apollodata.com/react/server-side-rendering.html#getDataFromTree). This method returns a promise; at the point in which the promise resolves, our Apollo Client store is completely initialized. This example relies on [graph.cool](https://www.graph.cool) for its GraphQL backend. + +### Note: +In these *with-apollo* examples, the ```withData()``` HOC must wrap a top-level component from within the ```pages``` directory. Wrapping a child component with the HOC will result in a ```Warning: Failed prop type: The prop 'serverState' is marked as required in 'WithData(Apollo(Component))', but its value is 'undefined'``` error. Down-tree child components will have access to Apollo, and can be wrapped with any other sort of ```graphql()```, ```compose()```, etc HOC's. diff --git a/examples/with-apollo/lib/withData.js b/examples/with-apollo/lib/withData.js index d854618a..2e6326bc 100644 --- a/examples/with-apollo/lib/withData.js +++ b/examples/with-apollo/lib/withData.js @@ -32,9 +32,16 @@ export default ComposedComponent => { // and extract the resulting data const apollo = initApollo() try { + // create the url prop which is passed to every page + const url = { + query: ctx.query, + asPath: ctx.asPath, + pathname: ctx.pathname, + }; + // Run all GraphQL queries await getDataFromTree( - , + , { router: { asPath: ctx.asPath, diff --git a/examples/with-cerebral/components/Page.js b/examples/with-cerebral/components/Page.js index 28e4485b..04a800c9 100644 --- a/examples/with-cerebral/components/Page.js +++ b/examples/with-cerebral/components/Page.js @@ -10,24 +10,24 @@ export default connect({ mounted: signal`clock.mounted`, unMounted: signal`clock.unMounted` }, - class Page extends React.Component { - componentDidMount () { - this.props.mounted() - } - - componentWillUnmount () { - this.props.unMounted() - } - render () { - return ( -
-

{this.props.title}

- - -
- ) - } +class Page extends React.Component { + componentDidMount () { + this.props.mounted() } + + componentWillUnmount () { + this.props.unMounted() + } + render () { + return ( +
+

{this.props.title}

+ + +
+ ) + } +} ) diff --git a/examples/with-draft-js/pages/index.js b/examples/with-draft-js/pages/index.js index 286b3305..d415b2e5 100644 --- a/examples/with-draft-js/pages/index.js +++ b/examples/with-draft-js/pages/index.js @@ -5,7 +5,7 @@ import { RichUtils, convertToRaw, convertFromRaw - } from 'draft-js' +} from 'draft-js' export default class App extends React.Component { constructor (props) { @@ -62,7 +62,7 @@ export default class App extends React.Component { setSelectionXY = () => { var r = window.getSelection().getRangeAt(0).getBoundingClientRect() var relative = document.body.parentNode.getBoundingClientRect() - // 2-a Set the selection coordinates in the state + // 2-a Set the selection coordinates in the state this.setState({ selectionCoordinates: r, windowWidth: relative.width, @@ -176,7 +176,7 @@ export default class App extends React.Component { this.elemHeight = elem ? elem.clientHeight : 0 }} style={toolbarStyle} - > + > { label={toolbarItem.label} onToggle={props.onToggle} style={toolbarItem.style} - /> - )} + /> + )} ) } diff --git a/examples/with-firebase-authentication/credentials/client.js b/examples/with-firebase-authentication/credentials/client.js index a9482b25..ce2ff946 100644 --- a/examples/with-firebase-authentication/credentials/client.js +++ b/examples/with-firebase-authentication/credentials/client.js @@ -1,3 +1,3 @@ module.exports = { - // TODO firebase client config + // TODO firebase client config } diff --git a/examples/with-firebase-authentication/credentials/server.js b/examples/with-firebase-authentication/credentials/server.js index aa1ebc6d..dd94ff16 100644 --- a/examples/with-firebase-authentication/credentials/server.js +++ b/examples/with-firebase-authentication/credentials/server.js @@ -1,3 +1,3 @@ module.exports = { - // TODO firebase server config + // TODO firebase server config } diff --git a/examples/with-firebase-authentication/pages/index.js b/examples/with-firebase-authentication/pages/index.js index 849736da..b6ef3f73 100644 --- a/examples/with-firebase-authentication/pages/index.js +++ b/examples/with-firebase-authentication/pages/index.js @@ -90,8 +90,8 @@ export default class Index extends Component { return
{ user - ? - : + ? + : } { user && diff --git a/examples/with-firebase-authentication/server.js b/examples/with-firebase-authentication/server.js index ec060a84..10919407 100644 --- a/examples/with-firebase-authentication/server.js +++ b/examples/with-firebase-authentication/server.js @@ -16,49 +16,49 @@ const firebase = admin.initializeApp({ }, 'server') app.prepare() -.then(() => { - const server = express() + .then(() => { + const server = express() - server.use(bodyParser.json()) - server.use(session({ - secret: 'geheimnis', - saveUninitialized: true, - store: new FileStore({path: '/tmp/sessions', secret: 'geheimnis'}), - resave: false, - rolling: true, - httpOnly: true, - cookie: { maxAge: 604800000 } // week - })) + server.use(bodyParser.json()) + server.use(session({ + secret: 'geheimnis', + saveUninitialized: true, + store: new FileStore({path: '/tmp/sessions', secret: 'geheimnis'}), + resave: false, + rolling: true, + httpOnly: true, + cookie: { maxAge: 604800000 } // week + })) - server.use((req, res, next) => { - req.firebaseServer = firebase - next() + server.use((req, res, next) => { + req.firebaseServer = firebase + next() + }) + + server.post('/api/login', (req, res) => { + if (!req.body) return res.sendStatus(400) + + const token = req.body.token + firebase.auth().verifyIdToken(token) + .then((decodedToken) => { + req.session.decodedToken = decodedToken + return decodedToken + }) + .then((decodedToken) => res.json({ status: true, decodedToken })) + .catch((error) => res.json({ error })) + }) + + server.post('/api/logout', (req, res) => { + req.session.decodedToken = null + res.json({ status: true }) + }) + + server.get('*', (req, res) => { + return handle(req, res) + }) + + server.listen(port, (err) => { + if (err) throw err + console.log(`> Ready on http://localhost:${port}`) + }) }) - - server.post('/api/login', (req, res) => { - if (!req.body) return res.sendStatus(400) - - const token = req.body.token - firebase.auth().verifyIdToken(token) - .then((decodedToken) => { - req.session.decodedToken = decodedToken - return decodedToken - }) - .then((decodedToken) => res.json({ status: true, decodedToken })) - .catch((error) => res.json({ error })) - }) - - server.post('/api/logout', (req, res) => { - req.session.decodedToken = null - res.json({ status: true }) - }) - - server.get('*', (req, res) => { - return handle(req, res) - }) - - server.listen(port, (err) => { - if (err) throw err - console.log(`> Ready on http://localhost:${port}`) - }) -}) diff --git a/examples/with-global-stylesheet/next.config.js b/examples/with-global-stylesheet/next.config.js index f8935363..b9836034 100644 --- a/examples/with-global-stylesheet/next.config.js +++ b/examples/with-global-stylesheet/next.config.js @@ -11,12 +11,12 @@ module.exports = { name: 'dist/[path][name].[ext]' } } - , + , { test: /\.css$/, use: ['babel-loader', 'raw-loader', 'postcss-loader'] } - , + , { test: /\.s(a|c)ss$/, use: ['babel-loader', 'raw-loader', 'postcss-loader', diff --git a/examples/with-google-analytics/README.md b/examples/with-google-analytics/README.md new file mode 100644 index 00000000..766aab7a --- /dev/null +++ b/examples/with-google-analytics/README.md @@ -0,0 +1,41 @@ +[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-google-analytics) + +# Example app with analytics + +## How to use + +### Using `create-next-app` + +Download [`create-next-app`](https://github.com/segmentio/create-next-app) to bootstrap the example: + +```bash +npx create-next-app --example with-google-analytics with-google-analytics-app +# or +yarn create next-app --example with-google-analytics with-google-analytics-app +``` + +### Download manually + +Download the example [or clone the repo](https://github.com/zeit/next.js): + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-google-analytics +cd with-google-analytics +``` + +Install it and run: + +```bash +yarn +yarn dev +``` + +Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)) + +```bash +now +``` + +## The idea behind the example + +This example shows how to use [Next.js](https://github.com/zeit/next.js) along with [Google Analytics](https://developers.google.com/analytics/devguides/collection/gtagjs/). A custom [\_document](https://github.com/zeit/next.js/#custom-document) is used to inject [tracking snippet](https://developers.google.com/analytics/devguides/collection/gtagjs/) and track [pageviews](https://developers.google.com/analytics/devguides/collection/gtagjs/pages) and [event](https://developers.google.com/analytics/devguides/collection/gtagjs/events). diff --git a/examples/with-google-analytics/components/Header.js b/examples/with-google-analytics/components/Header.js new file mode 100644 index 00000000..9739e3ea --- /dev/null +++ b/examples/with-google-analytics/components/Header.js @@ -0,0 +1,26 @@ +import React from 'react' +import Link from 'next/link' + +export default () => ( +
+ +
+) diff --git a/examples/with-google-analytics/components/Page.js b/examples/with-google-analytics/components/Page.js new file mode 100644 index 00000000..421c5f2b --- /dev/null +++ b/examples/with-google-analytics/components/Page.js @@ -0,0 +1,16 @@ +import React from 'react' +import Router from 'next/router' +import Header from './Header' + +import * as gtag from '../lib/gtag' + +Router.onRouteChangeComplete = url => { + gtag.pageview(url) +} + +export default ({ children }) => ( +
+
+ {children} +
+) diff --git a/examples/with-google-analytics/lib/gtag.js b/examples/with-google-analytics/lib/gtag.js new file mode 100644 index 00000000..3279ca6f --- /dev/null +++ b/examples/with-google-analytics/lib/gtag.js @@ -0,0 +1,17 @@ +export const GA_TRACKING_ID = '' + +// https://developers.google.com/analytics/devguides/collection/gtagjs/pages +export const pageview = url => { + window.gtag('config', GA_TRACKING_ID, { + page_location: url, + }) +} + +// https://developers.google.com/analytics/devguides/collection/gtagjs/events +export const event = ({ action, category, label, value }) => { + window.gtag('event', action, { + event_category: category, + event_label: label, + value: value, + }) +} diff --git a/examples/with-google-analytics/package.json b/examples/with-google-analytics/package.json new file mode 100644 index 00000000..ba89a717 --- /dev/null +++ b/examples/with-google-analytics/package.json @@ -0,0 +1,13 @@ +{ + "name": "with-google-analytics", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "latest", + "react": "^16.2.0", + "react-dom": "^16.2.0" + } +} diff --git a/examples/with-google-analytics/pages/_document.js b/examples/with-google-analytics/pages/_document.js new file mode 100644 index 00000000..27b8a85d --- /dev/null +++ b/examples/with-google-analytics/pages/_document.js @@ -0,0 +1,41 @@ +import React from 'react' +import Document, { Head, Main, NextScript } from 'next/document' +import flush from 'styled-jsx/server' + +import { GA_TRACKING_ID } from '../lib/gtag' + +export default class extends Document { + static getInitialProps ({ renderPage }) { + const { html, head, errorHtml, chunks } = renderPage() + const styles = flush() + return { html, head, errorHtml, chunks, styles } + } + + render () { + return ( + + + {/* Global Site Tag (gtag.js) - Google Analytics */} +