diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..922d92a --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# 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 +.env* + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/README.md b/README.md new file mode 100644 index 0000000..e1ac6c9 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# Pass Server Data Directly to a Next.js Page during SSR + +## 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-emotion-fiber) + +## How to use + +### Using `create-next-app` + +Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example: + +```bash +npx create-next-app --example with-emotion-fiber with-emotion-fiber-app +# or +yarn create next-app --example with-emotion-fiber with-emotion-fiber-app +``` + +### Download manually + +Download the example: + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-emotion-fiber +cd with-emotion-fiber +``` + +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 +``` + +## The idea behind the example + +Extract and inline critical css with [emotion](https://github.com/emotion-js/emotion) using [emotion-server](https://github.com/emotion-js/emotion/tree/master/packages/emotion-server) and [react-emotion](https://github.com/emotion-js/emotion/tree/master/packages/react-emotion). diff --git a/features/home.component.js b/features/home.component.js new file mode 100644 index 0000000..c8ec563 --- /dev/null +++ b/features/home.component.js @@ -0,0 +1,12 @@ +import { Basic, Combined, Animated, bounce } from '../shared/styles' +const Home = () => ( +
+ Cool Styles + + With :hover. + + Let's bounce. +
+) + +export default Home diff --git a/hoc/withEmotion.component.js b/hoc/withEmotion.component.js new file mode 100644 index 0000000..6c0c5c0 --- /dev/null +++ b/hoc/withEmotion.component.js @@ -0,0 +1,22 @@ +import React, { Component } from 'react' +import { hydrate } from 'react-emotion' +import { injectGlobalStyles } from '../shared/styles' + +const withEmotion = ComposedComponent => { + class HOC extends Component { + UNSAFE_componentWillMount() { + if (typeof window !== 'undefined') { + hydrate(window.__NEXT_DATA__.ids) + } + injectGlobalStyles() + } + + render() { + return + } + } + + return HOC +} + +export default withEmotion diff --git a/package.json b/package.json new file mode 100644 index 0000000..c06dcb5 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "with-emotion-fiber", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "keywords": [], + "author": "Thomas Greco", + "license": "ISC", + "dependencies": { + "emotion": "^8.0.11", + "emotion-server": "^8.0.11", + "next": "latest", + "react": "^16.7.0", + "react-dom": "^16.7.0", + "react-emotion": "^8.0.11" + } +} diff --git a/pages/_document.js b/pages/_document.js new file mode 100644 index 0000000..a7c1502 --- /dev/null +++ b/pages/_document.js @@ -0,0 +1,32 @@ +import Document, { Head, Main, NextScript } from 'next/document' +import { extractCritical } from 'emotion-server' + +export default class MyDocument extends Document { + static getInitialProps({ renderPage }) { + const page = renderPage() + const styles = extractCritical(page.html) + return { ...page, ...styles } + } + + constructor(props) { + super(props) + const { __NEXT_DATA__, ids } = props + if (ids) { + __NEXT_DATA__.ids = ids + } + } + + render() { + return ( + + +