diff --git a/client/index.js b/client/index.js index f14cb395..7ffe6605 100644 --- a/client/index.js +++ b/client/index.js @@ -21,6 +21,7 @@ const { __NEXT_DATA__: { props, err, + page, pathname, query, buildId, @@ -76,7 +77,7 @@ export default async ({ ErrorDebugComponent: passedDebugComponent, stripAnsi: pa ErrorComponent = await pageLoader.loadPage('/_error') try { - Component = await pageLoader.loadPage(pathname) + Component = await pageLoader.loadPage(page) } catch (err) { console.error(stripAnsi(`${err.message}\n${err.stack}`)) Component = ErrorComponent diff --git a/errors/powered-by-header-option-removed.md b/errors/powered-by-header-option-removed.md deleted file mode 100644 index 216fbda8..00000000 --- a/errors/powered-by-header-option-removed.md +++ /dev/null @@ -1,15 +0,0 @@ -# The poweredByHeader has been removed - -#### Why This Error Occurred - -Starting at Next.js version 5.0.0 the `poweredByHeader` option has been removed. - -#### Possible Ways to Fix It - -If you still want to remove `x-powered-by` you can use one of the custom-server examples. - -And then manually remove the header using `res.removeHeader('x-powered-by')` - -### Useful Links - -- [Custom Server documentation + examples](https://github.com/zeit/next.js#custom-server-and-routing) diff --git a/examples/active-class-name/components/Link.js b/examples/active-class-name/components/Link.js index 9ac3eaa9..eadf822e 100644 --- a/examples/active-class-name/components/Link.js +++ b/examples/active-class-name/components/Link.js @@ -5,9 +5,9 @@ import React, { Children } from 'react' const ActiveLink = ({ router, children, ...props }) => { const child = Children.only(children) - let className = child.props.className || '' + let className = child.props.className || null if (router.pathname === props.href && props.activeClassName) { - className = `${className} ${props.activeClassName}`.trim() + className = `${className !== null ? className : ''} ${props.activeClassName}`.trim() } delete props.activeClassName diff --git a/examples/custom-charset/package.json b/examples/custom-charset/package.json new file mode 100644 index 00000000..d9a8a33c --- /dev/null +++ b/examples/custom-charset/package.json @@ -0,0 +1,14 @@ +{ + "name": "custom-server", + "version": "1.0.0", + "scripts": { + "dev": "node server.js", + "build": "next build", + "start": "NODE_ENV=production node server.js" + }, + "dependencies": { + "next": "latest", + "react": "^16.0.0", + "react-dom": "^16.0.0" + } +} diff --git a/examples/custom-charset/pages/README.md b/examples/custom-charset/pages/README.md new file mode 100644 index 00000000..cc4798c6 --- /dev/null +++ b/examples/custom-charset/pages/README.md @@ -0,0 +1,34 @@ +[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/custom-server) + +# Custom server example + +## How to use + +### 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/custom-charset +cd custom-charset +``` + +Install it and run: + +```bash +npm install +npm run dev +``` + +Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)) + +```bash +now +``` + +## The idea behind the example + +The HTTP/1.1 specification says - if charset is not set in the http header then the browser defaults use ISO-8859-1. +For languages like Polish, Albanian, Hungarian, Czech, Slovak, Slovene, there will be broken characters encoding from SSR. + +You can overwrite Content-Type in getInitialProps. But if you want to handle it as a server side concern, you can use this as an simple example. diff --git a/examples/custom-charset/pages/index.js b/examples/custom-charset/pages/index.js new file mode 100644 index 00000000..0e0c34eb --- /dev/null +++ b/examples/custom-charset/pages/index.js @@ -0,0 +1,3 @@ +import React from 'react' + +export default () =>
áéíóöúü
diff --git a/examples/custom-charset/server.js b/examples/custom-charset/server.js new file mode 100644 index 00000000..bf8b0a43 --- /dev/null +++ b/examples/custom-charset/server.js @@ -0,0 +1,21 @@ +const { createServer } = require('http') +const { parse } = require('url') +const next = require('next') + +const port = parseInt(process.env.PORT, 10) || 3000 +const dev = process.env.NODE_ENV !== 'production' +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) + }) + .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 11a1d98e..8f0ef4d8 100644 --- a/examples/ssr-caching/server.js +++ b/examples/ssr-caching/server.js @@ -45,26 +45,32 @@ function getCacheKey (req) { return `${req.url}` } -function renderAndCache (req, res, pagePath, queryParams) { +async function renderAndCache (req, res, pagePath, queryParams) { const key = getCacheKey(req) // If we have a page in the cache, let's serve it if (ssrCache.has(key)) { - console.log(`CACHE HIT: ${key}`) + res.setHeader('x-cache', 'HIT') res.send(ssrCache.get(key)) return } - // If not let's render the page into HTML - app.renderToHTML(req, res, pagePath, queryParams) - .then((html) => { - // Let's cache this page - console.log(`CACHE MISS: ${key}`) - ssrCache.set(key, html) + try { + // If not let's render the page into HTML + const html = await app.renderToHTML(req, res, pagePath, queryParams) + // Something is wrong with the request, let's skip the cache + if (res.statusCode !== 200) { res.send(html) - }) - .catch((err) => { - app.renderError(err, req, res, pagePath, queryParams) - }) + return + } + + // Let's cache this page + ssrCache.set(key, html) + + res.setHeader('x-cache', 'MISS') + res.send(html) + } catch (err) { + app.renderError(err, req, res, pagePath, queryParams) + } } diff --git a/examples/svg-components/package.json b/examples/svg-components/package.json index 65f3541d..46e131f1 100644 --- a/examples/svg-components/package.json +++ b/examples/svg-components/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "next": "latest", - "react": "latest, + "react": "latest", "react-dom": "latest" }, "devDependencies": { diff --git a/examples/with-apollo-auth/pages/index.js b/examples/with-apollo-auth/pages/index.js index 8250bac4..eb1fd6f3 100644 --- a/examples/with-apollo-auth/pages/index.js +++ b/examples/with-apollo-auth/pages/index.js @@ -25,7 +25,7 @@ class Index extends React.Component { // Force a reload of all the current queries now that the user is // logged in, so we don't accidentally leave any state around. - this.props.client.resetStore().then(() => { + this.props.client.cache.reset().then(() => { // Redirect to a more useful page when signed out redirect({}, '/signin') }) diff --git a/examples/with-apollo-auth/test/shared-apollo.js b/examples/with-apollo-auth/test/shared-apollo.js index 8b3684f4..adf1a2a8 100644 --- a/examples/with-apollo-auth/test/shared-apollo.js +++ b/examples/with-apollo-auth/test/shared-apollo.js @@ -18,7 +18,7 @@ const test = require('ava') * Apollo that we can clear, etc */ -const apolloFilePath = require.resolve('../lib/init-apollo') +const apolloFilePath = require.resolve('../lib/initApollo') test.beforeEach(() => { // Clean up the cache diff --git a/examples/with-apollo/README.md b/examples/with-apollo/README.md index fd83de0e..bbf1f857 100644 --- a/examples/with-apollo/README.md +++ b/examples/with-apollo/README.md @@ -47,5 +47,3 @@ 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: Apollo uses Redux internally; if you're interested in integrating the client with your existing Redux store check out the [`with-apollo-and-redux`](https://github.com/zeit/next.js/tree/master/examples/with-apollo-and-redux) example.* diff --git a/examples/with-draft-js/README.md b/examples/with-draft-js/README.md new file mode 100644 index 00000000..5a9c90ac --- /dev/null +++ b/examples/with-draft-js/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-draft-js) +# DraftJS Medium editor inspiration + +## How to use + +### Using `create-next-app` + +Download [`create-next-app`](https://github.com/segmentio/create-next-app) to bootstrap the example: + +``` +npm i -g create-next-app +create-next-app --example with-draft-js +``` + +### 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-draft-js +cd with-draft-js +``` + +Install it and run: + +```bash +npm install +npm run dev +``` + +Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)): + +```bash +now +``` + +## The idea behind the example + +Have you ever wanted to have an editor like medium.com in your Next.js app? DraftJS is avalaible for SSR, but some plugins like the toolbar are using `window`, which does not work when doing SSR. + +This example aims to provides a fully customizable example of the famous medium editor with DraftJS. The goal was to get it as customizable as possible, and fully working with Next.js without using the react-no-ssr package. diff --git a/examples/with-draft-js/package.json b/examples/with-draft-js/package.json new file mode 100644 index 00000000..fdb9eccd --- /dev/null +++ b/examples/with-draft-js/package.json @@ -0,0 +1,17 @@ +{ + "name": "with-draft-js", + "version": "1.0.0", + "author": "Asten Mies", + "license": "ISC", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "draft-js": "0.10.5", + "next": "5.0.0", + "react": "16.2.0", + "react-dom": "16.2.0" + } +} diff --git a/examples/with-draft-js/pages/index.js b/examples/with-draft-js/pages/index.js new file mode 100644 index 00000000..286b3305 --- /dev/null +++ b/examples/with-draft-js/pages/index.js @@ -0,0 +1,270 @@ +import React from 'react' +import { + Editor, + EditorState, + RichUtils, + convertToRaw, + convertFromRaw + } from 'draft-js' + +export default class App extends React.Component { + constructor (props) { + super(props) + this.state = { + editorState: EditorState.createWithContent(convertFromRaw(initialData)), + showToolbar: false, + windowWidth: 0, + toolbarMeasures: { + w: 0, + h: 0 + }, + selectionMeasures: { + w: 0, + h: 0 + }, + selectionCoordinates: { + x: 0, + y: 0 + }, + toolbarCoordinates: { + x: 0, + y: 0 + }, + showRawData: false + } + + this.focus = () => this.editor.focus() + this.onChange = (editorState) => this.setState({editorState}) + } + + onClickEditor = () => { + this.focus() + this.checkSelectedText() + } + + // 1- Check if some text is selected + checkSelectedText = () => { + if (typeof window !== 'undefined') { + const text = window.getSelection().toString() + if (text !== '') { + // 1-a Define the selection coordinates + this.setSelectionXY() + } else { + // Hide the toolbar if nothing is selected + this.setState({ + showToolbar: false + }) + } + } + } + + // 2- Identify the selection coordinates + setSelectionXY = () => { + var r = window.getSelection().getRangeAt(0).getBoundingClientRect() + var relative = document.body.parentNode.getBoundingClientRect() + // 2-a Set the selection coordinates in the state + this.setState({ + selectionCoordinates: r, + windowWidth: relative.width, + selectionMeasures: { + w: r.width, + h: r.height + } + }, () => this.showToolbar()) + } + + // 3- Show the toolbar + showToolbar = () => { + this.setState({ + showToolbar: true + }, () => this.measureToolbar()) + } + + // 4- The toolbar was hidden until now + measureToolbar = () => { + // 4-a Define the toolbar width and height, as it is now visible + this.setState({ + toolbarMeasures: { + w: this.elemWidth, + h: this.elemHeight + } + }, () => this.setToolbarXY()) + } + + // 5- Now that we have all measures, define toolbar coordinates + setToolbarXY = () => { + let coordinates = {} + + const { selectionMeasures, selectionCoordinates, toolbarMeasures, windowWidth } = this.state + + const hiddenTop = selectionCoordinates.y < toolbarMeasures.h + const hiddenRight = windowWidth - selectionCoordinates.x < toolbarMeasures.w / 2 + const hiddenLeft = selectionCoordinates.x < toolbarMeasures.w / 2 + + const normalX = selectionCoordinates.x - (toolbarMeasures.w / 2) + (selectionMeasures.w / 2) + const normalY = selectionCoordinates.y - toolbarMeasures.h + + const invertedY = selectionCoordinates.y + selectionMeasures.h + const moveXToLeft = windowWidth - toolbarMeasures.w + const moveXToRight = 0 + + coordinates = { + x: normalX, + y: normalY + } + + if (hiddenTop) { + coordinates.y = invertedY + } + + if (hiddenRight) { + coordinates.x = moveXToLeft + } + + if (hiddenLeft) { + coordinates.x = moveXToRight + } + + this.setState({ + toolbarCoordinates: coordinates + }) + } + + handleKeyCommand = (command) => { + const {editorState} = this.state + const newState = RichUtils.handleKeyCommand(editorState, command) + if (newState) { + this.onChange(newState) + return true + } + return false + } + + toggleToolbar = (inlineStyle) => { + this.onChange( + RichUtils.toggleInlineStyle( + this.state.editorState, + inlineStyle + ) + ) + } + + render () { + const {editorState} = this.state + // Make sure we're not on the ssr + if (typeof window !== 'undefined') { + // Let's stick the toolbar to the selection + // when the window is resized + window.addEventListener('resize', this.checkSelectedText) + } + + const toolbarStyle = { + display: this.state.showToolbar ? 'block' : 'none', + backgroundColor: 'black', + color: 'white', + position: 'absolute', + left: this.state.toolbarCoordinates.x, + top: this.state.toolbarCoordinates.y, + zIndex: 999, + padding: 10 + } + return ( +
+
{ + this.elemWidth = elem ? elem.clientWidth : 0 + this.elemHeight = elem ? elem.clientHeight : 0 + }} + style={toolbarStyle} + > + +
+
+ { this.editor = element }} + /> +
+
+
+ {this.state.showRawData && JSON.stringify(convertToRaw(editorState.getCurrentContent()))} +
+
+ ) + } +} + +// Custom overrides for each style +const styleMap = { + CODE: { + backgroundColor: 'rgba(0, 0, 0, 0.05)', + fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace', + fontSize: 16, + padding: 4 + }, + BOLD: { + color: '#395296', + fontWeight: 'bold' + }, + ANYCUSTOMSTYLE: { + color: '#00e400' + } +} + +class ToolbarButton extends React.Component { + constructor () { + super() + this.onToggle = (e) => { + e.preventDefault() + this.props.onToggle(this.props.style) + } + } + + render () { + const buttonStyle = { + padding: 10 + } + return ( + + { this.props.label } + + ) + } +} + +var toolbarItems = [ + {label: 'Bold', style: 'BOLD'}, + {label: 'Italic', style: 'ITALIC'}, + {label: 'Underline', style: 'UNDERLINE'}, + {label: 'Code', style: 'CODE'}, + {label: 'Surprise', style: 'ANYCUSTOMSTYLE'} +] + +const ToolBar = (props) => { + var currentStyle = props.editorState.getCurrentInlineStyle() + return ( +
+ {toolbarItems.map(toolbarItem => + + )} +
+ ) +} + +const initialData = {'blocks': [{'key': '16d0k', 'text': 'You can edit this text.', 'type': 'unstyled', 'depth': 0, 'inlineStyleRanges': [{'offset': 0, 'length': 23, 'style': 'BOLD'}], 'entityRanges': [], 'data': {}}, {'key': '98peq', 'text': '', 'type': 'unstyled', 'depth': 0, 'inlineStyleRanges': [], 'entityRanges': [], 'data': {}}, {'key': 'ecmnc', 'text': 'Luke Skywalker has vanished. In his absence, the sinister FIRST ORDER has risen from the ashes of the Empire and will not rest until Skywalker, the last Jedi, has been destroyed.', 'type': 'unstyled', 'depth': 0, 'inlineStyleRanges': [{'offset': 0, 'length': 14, 'style': 'BOLD'}, {'offset': 133, 'length': 9, 'style': 'BOLD'}], 'entityRanges': [], 'data': {}}, {'key': 'fe2gn', 'text': '', 'type': 'unstyled', 'depth': 0, 'inlineStyleRanges': [], 'entityRanges': [], 'data': {}}, {'key': '4481k', 'text': 'With the support of the REPUBLIC, General Leia Organa leads a brave RESISTANCE. She is desperate to find her brother Luke and gain his help in restoring peace and justice to the galaxy.', 'type': 'unstyled', 'depth': 0, 'inlineStyleRanges': [{'offset': 34, 'length': 19, 'style': 'BOLD'}, {'offset': 117, 'length': 4, 'style': 'BOLD'}, {'offset': 68, 'length': 10, 'style': 'ANYCUSTOMSTYLE'}], 'entityRanges': [], 'data': {}}], 'entityMap': {}} diff --git a/examples/with-firebase-authentication/README.md b/examples/with-firebase-authentication/README.md index 4d275999..84f70244 100644 --- a/examples/with-firebase-authentication/README.md +++ b/examples/with-firebase-authentication/README.md @@ -23,10 +23,11 @@ cd with-firebase-authentication ``` Set up firebase: -- create a project -- get your service account credentials and client credentials and set both in firebaseCredentials.js -- set your firebase database url in server.js -- on the firebase Authentication console, select Google as your provider +- Create a project at the [Firebase console](https://console.firebase.google.com/). +- Get your account credentials from the Firebase console at *settings>service accounts*, where you can click on *generate new private key* and download the credentials as a json file. It will contain keys such as `project_id`, `client_email` and `client id`. Now copy them into your project in the `credentials/server.js` file. +- Get your authentication credentials from the Firebase console under *authentication>users>web setup*. It will include keys like `apiKey`, `authDomain` and `databaseUrl` and it goes into your project in `credentials/client.js`. +- Copy the `databaseUrl` key you got in the last step into `server.js` in the corresponding line. +- Back at the Firebase web console, go to *authentication>signup method* and select *Google*. Install it and run: diff --git a/examples/with-firebase-authentication/package.json b/examples/with-firebase-authentication/package.json index e2e632a3..28c3fcd8 100644 --- a/examples/with-firebase-authentication/package.json +++ b/examples/with-firebase-authentication/package.json @@ -10,8 +10,8 @@ "body-parser": "^1.17.1", "express": "^4.14.0", "express-session": "^1.15.2", - "firebase": "^3.7.5", - "firebase-admin": "^4.2.0", + "firebase": "^4.9.1", + "firebase-admin": "^5.8.2", "isomorphic-unfetch": "2.0.0", "next": "latest", "react": "^16.0.0", diff --git a/examples/with-glamor/pages/_document.js b/examples/with-glamor/pages/_document.js index c6572651..525cd21e 100644 --- a/examples/with-glamor/pages/_document.js +++ b/examples/with-glamor/pages/_document.js @@ -4,7 +4,7 @@ import { renderStatic } from 'glamor/server' export default class MyDocument extends Document { static async getInitialProps ({ renderPage }) { const page = renderPage() - const styles = renderStatic(() => page.html) + const styles = renderStatic(() => page.html || page.errorHtml) return { ...page, ...styles } } diff --git a/examples/with-glamorous/pages/_document.js b/examples/with-glamorous/pages/_document.js index 1d7d07af..63644fd9 100644 --- a/examples/with-glamorous/pages/_document.js +++ b/examples/with-glamorous/pages/_document.js @@ -4,7 +4,7 @@ import { renderStatic } from 'glamor/server' export default class MyDocument extends Document { static async getInitialProps ({ renderPage }) { const page = renderPage() - const styles = renderStatic(() => page.html) + const styles = renderStatic(() => page.html || page.errorHtml) return { ...page, ...styles } } diff --git a/examples/with-global-stylesheet/package.json b/examples/with-global-stylesheet/package.json index 72738a39..4166dea9 100644 --- a/examples/with-global-stylesheet/package.json +++ b/examples/with-global-stylesheet/package.json @@ -22,8 +22,5 @@ "react": "^16.0.0", "react-dom": "^16.0.0", "sass-loader": "^6.0.6" - }, - "devDependencies": { - "now": "^8.3.10" } } diff --git a/examples/with-mobx-state-tree/store.js b/examples/with-mobx-state-tree/store.js index 773beb69..798e5c89 100644 --- a/examples/with-mobx-state-tree/store.js +++ b/examples/with-mobx-state-tree/store.js @@ -14,7 +14,7 @@ const Store = types // mobx-state-tree doesn't allow anonymous callbacks changing data // pass off to another action instead self.update() - }) + }, 1000) } function update () { diff --git a/examples/with-mobx/store.js b/examples/with-mobx/store.js index ba88dce5..34d9abdc 100644 --- a/examples/with-mobx/store.js +++ b/examples/with-mobx/store.js @@ -14,7 +14,7 @@ class Store { this.timer = setInterval(() => { this.lastUpdate = Date.now() this.light = true - }) + }, 1000) } stop = () => clearInterval(this.timer) diff --git a/examples/with-next-css/README.md b/examples/with-next-css/README.md new file mode 100644 index 00000000..0451a991 --- /dev/null +++ b/examples/with-next-css/README.md @@ -0,0 +1,40 @@ +[![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-next-css) + +# next-css example + +## How to use + +### Using `create-next-app` + +Download [`create-next-app`](https://github.com/segmentio/create-next-app) to bootstrap the example: + +``` +npm i -g create-next-app +create-next-app --example with-next-css with-next-css-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-next-css +cd with-next-css +``` + +Install it and run: + +```bash +npm install +npm run 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 demonstrates how to use the [next-css plugin](https://github.com/zeit/next-plugins/tree/master/packages/next-css) It includes patterns for with and without CSS Modules, with PostCSS and with additional webpack configurations on top of the next-css plugin. \ No newline at end of file diff --git a/examples/with-next-css/next.config.js b/examples/with-next-css/next.config.js new file mode 100644 index 00000000..b6316525 --- /dev/null +++ b/examples/with-next-css/next.config.js @@ -0,0 +1,16 @@ +const withCSS = require('@zeit/next-css') +/* Without CSS Modules, with PostCSS */ +module.exports = withCSS() + +/* With CSS Modules */ +// module.exports = withCSS({ cssModules: true }) + +/* With additional configuration on top of CSS Modules */ +/* +module.exports = withCSS({ + cssModules: true, + webpack: function (config) { + return config; + } +}); +*/ diff --git a/examples/with-next-css/package.json b/examples/with-next-css/package.json new file mode 100644 index 00000000..65d5f264 --- /dev/null +++ b/examples/with-next-css/package.json @@ -0,0 +1,16 @@ +{ + "name": "with-css-modules", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "@zeit/next-css": "0.0.7", + "next": "5.0.0", + "react": "16.2.0", + "react-dom": "16.2.0" + } +} diff --git a/examples/with-next-css/pages/_document.js b/examples/with-next-css/pages/_document.js new file mode 100644 index 00000000..512ea5e4 --- /dev/null +++ b/examples/with-next-css/pages/_document.js @@ -0,0 +1,23 @@ +/* +In production the stylesheet is compiled to .next/static/style.css and served from /_next/static/style.css + +You have to include it into the page using either next/head or a custom _document.js, as is being done in this file. +*/ + +import Document, { Head, Main, NextScript } from 'next/document' + +export default class MyDocument extends Document { + render () { + return ( + + + + + +
+ + + + ) + } +} diff --git a/examples/with-next-css/pages/index.js b/examples/with-next-css/pages/index.js new file mode 100644 index 00000000..1c8ec8c0 --- /dev/null +++ b/examples/with-next-css/pages/index.js @@ -0,0 +1,13 @@ + +/* Without CSS Modules, maybe with PostCSS */ + +import '../style.css' + +export default () =>
O Hai world!
+ +/* With CSS Modules */ +/* +import css from "../style.css" + +export default () =>
Hello World, I am being styled using CSS Modules!
+*/ diff --git a/examples/with-next-css/style.css b/examples/with-next-css/style.css new file mode 100644 index 00000000..ace395e6 --- /dev/null +++ b/examples/with-next-css/style.css @@ -0,0 +1,16 @@ +.example { + font-size: 50px; + color: papayawhip; +} + +/* Post-CSS */ +/* +:root { + --some-color: red; +} + +.example { + color: var(--some-color); +} + +*/ diff --git a/examples/with-next-sass/next.config.js b/examples/with-next-sass/next.config.js new file mode 100644 index 00000000..ed73b137 --- /dev/null +++ b/examples/with-next-sass/next.config.js @@ -0,0 +1,2 @@ +const withSass = require('@zeit/next-sass') +module.exports = withSass() diff --git a/examples/with-next-sass/package.json b/examples/with-next-sass/package.json new file mode 100644 index 00000000..c6c7a56f --- /dev/null +++ b/examples/with-next-sass/package.json @@ -0,0 +1,14 @@ +{ + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "@zeit/next-sass": "0.0.9", + "next": "^5.0.0", + "node-sass": "^4.7.2", + "react": "^16.2.0", + "react-dom": "^16.2.0" + } +} diff --git a/examples/with-next-sass/pages/_document.js b/examples/with-next-sass/pages/_document.js new file mode 100644 index 00000000..af0f233e --- /dev/null +++ b/examples/with-next-sass/pages/_document.js @@ -0,0 +1,26 @@ +/* +In production the stylesheet is compiled to .next/static/style.css. +The file will be served from /_next/static/style.css +You could include it into the page using either next/head or a custom _document.js. +*/ + +import Document, { Head, Main, NextScript } from 'next/document' + +export default class MyDocument extends Document { + render () { + return ( + + + + + +
+ + + + ) + } +} diff --git a/examples/with-next-sass/pages/index.js b/examples/with-next-sass/pages/index.js new file mode 100644 index 00000000..64f64c0d --- /dev/null +++ b/examples/with-next-sass/pages/index.js @@ -0,0 +1,6 @@ +import '../styles/style.scss' + +export default () => +
+ Hello World! +
diff --git a/examples/with-next-sass/readme.md b/examples/with-next-sass/readme.md new file mode 100644 index 00000000..b17cfe3f --- /dev/null +++ b/examples/with-next-sass/readme.md @@ -0,0 +1,43 @@ +[![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-jest) + +# Example app with next-sass + +## How to use + +### Using `create-next-app` + +Download [`create-next-app`](https://github.com/segmentio/create-next-app) to bootstrap the example: + +```bash +npm i -g create-next-app +create-next-app --example with-next-sass with-next-sass-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-next-sass +cd with-next-sass +``` + +Install it and run: + +```bash +npm install +npm run build +npm run start +``` + +The dev mode is also support via `npm run dev` + +## The idea behind the example + +This example features: + +* An app with next-sass + +This example uses next-sass without css-modules. The config can be found in `next.config.js`, change `withSass()` to `withSass({cssModules: true})` if you use css-modules. Then in the code, you import the stylesheet as `import style '../styles/style.scss'` and use it like `
`. + +[Learn more](https://github.com/zeit/next-plugins/tree/master/packages/next-sass) diff --git a/examples/with-next-sass/styles/style.scss b/examples/with-next-sass/styles/style.scss new file mode 100644 index 00000000..73cc2e0e --- /dev/null +++ b/examples/with-next-sass/styles/style.scss @@ -0,0 +1,4 @@ +$color: #2ecc71; +.example { + background-color: $color; +} diff --git a/examples/with-polyfills/next.config.js b/examples/with-polyfills/next.config.js index eca79708..67527712 100644 --- a/examples/with-polyfills/next.config.js +++ b/examples/with-polyfills/next.config.js @@ -3,7 +3,11 @@ module.exports = { const originalEntry = cfg.entry cfg.entry = async () => { const entries = await originalEntry() - entries['main.js'].unshift('./client/polyfills.js') + + if (entries['main.js']) { + entries['main.js'].unshift('./client/polyfills.js') + } + return entries } diff --git a/examples/with-react-i18next/package.json b/examples/with-react-i18next/package.json index a427dfcd..f69b9713 100644 --- a/examples/with-react-i18next/package.json +++ b/examples/with-react-i18next/package.json @@ -11,15 +11,15 @@ "author": "", "license": "MIT", "dependencies": { - "express": "4.15.3", - "i18next": "8.4.2", - "i18next-browser-languagedetector": "2.0.0", - "i18next-express-middleware": "1.0.5", + "express": "4.16.2", + "i18next": "10.4.1", + "i18next-browser-languagedetector": "2.1.0", + "i18next-express-middleware": "1.0.10", "i18next-node-fs-backend": "1.0.0", - "i18next-xhr-backend": "1.4.2", - "next": "latest", + "i18next-xhr-backend": "1.5.1", + "next": "5.0.0", "react": "16.2.0", "react-dom": "16.2.0", - "react-i18next": "4.6.3" + "react-i18next": "7.3.6" } } diff --git a/examples/with-react-i18next/server.js b/examples/with-react-i18next/server.js index d3b62e80..5f2686e8 100644 --- a/examples/with-react-i18next/server.js +++ b/examples/with-react-i18next/server.js @@ -2,7 +2,6 @@ const express = require('express') const path = require('path') const next = require('next') -const port = parseInt(process.env.PORT, 10) || 3000 const dev = process.env.NODE_ENV !== 'production' const app = next({ dev }) const handle = app.getRequestHandler() @@ -17,6 +16,7 @@ i18n .use(Backend) .use(i18nextMiddleware.LanguageDetector) .init({ + fallbackLng: 'en', preload: ['en', 'de'], // preload all langages ns: ['common', 'home', 'page2'], // need to preload all the namespaces backend: { @@ -41,9 +41,9 @@ i18n // use next.js server.get('*', (req, res) => handle(req, res)) - server.listen(port, (err) => { + server.listen(3000, (err) => { if (err) throw err - console.log(`> Ready on http://localhost:${port}`) + console.log('> Ready on http://localhost:3000') }) }) }) diff --git a/examples/with-react-native-web/.babelrc b/examples/with-react-native-web/.babelrc new file mode 100644 index 00000000..e39892d3 --- /dev/null +++ b/examples/with-react-native-web/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["next/babel"], + "plugins": ["react-native-web"] +} diff --git a/examples/with-react-native-web/README.md b/examples/with-react-native-web/README.md new file mode 100644 index 00000000..1e4f14f3 --- /dev/null +++ b/examples/with-react-native-web/README.md @@ -0,0 +1,42 @@ +[![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-react-native-web) + +## How to use + +### Using `create-next-app` + +Download [`create-next-app`](https://github.com/segmentio/create-next-app) to bootstrap the example: + +``` +npm i -g create-next-app +create-next-app --example with-react-native-web +``` + +### 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-react-native-web +cd with-react-native-web +``` + +Install it and run: + +```bash +npm install +npm run 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 features how to use [react-native-web](https://github.com/necolas/react-native-web) to bring the platform-agnostic Components and APIs of React Native to the web. + +> **High-quality user interfaces**: React Native for Web makes it easy to create fast, adaptive web UIs in JavaScript. It provides native-like interactions, support for multiple input modes (touch, mouse, keyboard), optimized vendor-prefixed styles, built-in support for RTL layout, built-in accessibility, and integrates with React Dev Tools. +> +> **Write once, render anywhere**: React Native for Web interoperates with existing React DOM components and is compatible with the majority of the React Native API. You can develop new components for native and web without rewriting existing code. React Native for Web can also render to HTML and critical CSS on the server using Node.js. diff --git a/examples/with-react-native-web/package.json b/examples/with-react-native-web/package.json new file mode 100644 index 00000000..bb9d6f82 --- /dev/null +++ b/examples/with-react-native-web/package.json @@ -0,0 +1,17 @@ +{ + "name": "with-react-native-web", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "latest", + "react": "^16.0.0", + "react-dom": "^16.0.0", + "react-native-web": "^0.4.0" + }, + "devDependencies": { + "babel-plugin-react-native-web": "^0.4.0" + } +} diff --git a/examples/with-react-native-web/pages/_document.js b/examples/with-react-native-web/pages/_document.js new file mode 100644 index 00000000..0d99939f --- /dev/null +++ b/examples/with-react-native-web/pages/_document.js @@ -0,0 +1,45 @@ +import Document, { Head, Main, NextScript } from 'next/document' +import React from 'react' +import { AppRegistry } from 'react-native-web' + +let index = 0 + +// Force Next-generated DOM elements to fill their parent's height. +// Not required for using of react-native-web, but helps normalize +// layout for top-level wrapping elements. +const normalizeNextElements = ` + body > div:first-child, + #__next { + height: 100%; + } +` + +export default class MyDocument extends Document { + static async getInitialProps ({ renderPage }) { + AppRegistry.registerComponent('Main', () => Main) + const { getStyleElement } = AppRegistry.getApplication('Main') + const page = renderPage() + const styles = [ +