diff --git a/examples/with-apollo-auth/.babelrc b/examples/with-apollo-auth/.babelrc
deleted file mode 100644
index ca67af2f..00000000
--- a/examples/with-apollo-auth/.babelrc
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "env": {
- "development": {
- "presets": "next/babel"
- },
- "production": {
- "presets": "next/babel"
- },
- "test": {
- "presets": [
- ["env", { "modules": "commonjs" }],
- "next/babel"
- ]
- }
- }
-}
diff --git a/examples/with-apollo-auth/.gitignore b/examples/with-apollo-auth/.gitignore
deleted file mode 100644
index 4ed44b15..00000000
--- a/examples/with-apollo-auth/.gitignore
+++ /dev/null
@@ -1,80 +0,0 @@
-.next
-
-# Created by https://www.gitignore.io/api/vim,node
-
-### Node ###
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (http://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# Typescript v1 declaration files
-typings/
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variables file
-.env
-
-
-### Vim ###
-# swap
-[._]*.s[a-v][a-z]
-[._]*.sw[a-p]
-[._]s[a-v][a-z]
-[._]sw[a-p]
-# session
-Session.vim
-# temporary
-.netrwhist
-*~
-# auto-generated tag files
-tags
-
-# End of https://www.gitignore.io/api/vim,node
diff --git a/examples/with-apollo-auth/README.md b/examples/with-apollo-auth/README.md
index 281002f9..0ba86643 100644
--- a/examples/with-apollo-auth/README.md
+++ b/examples/with-apollo-auth/README.md
@@ -54,7 +54,7 @@ This is an extention of the _[with Apollo](https://github.com/zeit/next.js/tree/
>
> 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.*
+> *Note: 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.*
[graph.cool](https://www.graph.cool) can be setup with many different
[authentication providers](https://www.graph.cool/docs/reference/integrations/overview-seimeish6e/#authentication-providers), the most basic of which is [email-password authentication](https://www.graph.cool/docs/reference/simple-api/user-authentication-eixu9osueb/#email-and-password). Once email-password authentication is enabled for your graph.cool project, you are provided with 2 useful mutations: `createUser` and `signinUser`.
diff --git a/examples/with-apollo-auth/lib/checkLoggedIn.js b/examples/with-apollo-auth/lib/checkLoggedIn.js
index ee3d3933..29f198ba 100644
--- a/examples/with-apollo-auth/lib/checkLoggedIn.js
+++ b/examples/with-apollo-auth/lib/checkLoggedIn.js
@@ -1,6 +1,6 @@
import gql from 'graphql-tag'
-export default (context, apolloClient) => (
+export default apolloClient => (
apolloClient.query({
query: gql`
query getUser {
diff --git a/examples/with-apollo-auth/lib/withApollo.js b/examples/with-apollo-auth/lib/withApollo.js
new file mode 100644
index 00000000..a5101566
--- /dev/null
+++ b/examples/with-apollo-auth/lib/withApollo.js
@@ -0,0 +1,97 @@
+import React from 'react'
+import cookie from 'cookie'
+import PropTypes from 'prop-types'
+import { getDataFromTree } from 'react-apollo'
+import Head from 'next/head'
+
+import initApollo from './initApollo'
+
+function parseCookies(req, options = {}) {
+ return cookie.parse(
+ req && req.headers.cookie
+ ? req.headers.cookie
+ : document.cookie,
+ options
+ )
+}
+
+export default App => {
+ return class WithData extends React.Component {
+ static displayName = `WithData(${App.displayName})`
+ static propTypes = {
+ apolloState: PropTypes.shape({
+ data: PropTypes.object.isRequired
+ }).isRequired
+ }
+
+ static async getInitialProps(ctx) {
+ const { Component, router, ctx: { req, res } } = ctx
+ const apolloState = {}
+ const apollo = initApollo({}, {
+ getToken: () => parseCookies(req).token
+ })
+
+ ctx.ctx.apolloClient = apollo
+
+ let appProps = {}
+ if (App.getInitialProps) {
+ appProps = await App.getInitialProps(ctx)
+ }
+
+ if (res && res.finished) {
+ // When redirecting, the response is finished.
+ // No point in continuing to render
+ return {}
+ }
+
+ // Run all graphql queries in the component tree
+ // and extract the resulting data
+ try {
+ // Run all GraphQL queries
+ await getDataFromTree(
+
+ )
+ } catch (error) {
+ // Prevent Apollo Client GraphQL errors from crashing SSR.
+ // Handle them in components via the data.error prop:
+ // http://dev.apollodata.com/react/api-queries.html#graphql-query-data-error
+ console.error('Error while running `getDataFromTree`', error)
+ }
+
+ if (!process.browser) {
+ // getDataFromTree does not call componentWillUnmount
+ // head side effect therefore need to be cleared manually
+ Head.rewind()
+ }
+
+ // Extract query data from the Apollo's store
+ apolloState.data = apollo.cache.extract()
+
+ return {
+ ...appProps,
+ apolloState
+ }
+ }
+
+ constructor(props) {
+ super(props)
+ // `getDataFromTree` renders the component first, the client is passed off as a property.
+ // After that rendering is done using Next's normal rendering pipeline
+ this.apolloClient =
+ props.apolloClient ||
+ initApollo(props.apolloState.data, {
+ getToken: () => parseCookies().token
+ })
+ }
+
+ render() {
+ return
+ }
+ }
+}
diff --git a/examples/with-apollo-auth/lib/withData.js b/examples/with-apollo-auth/lib/withData.js
deleted file mode 100644
index fcec71ba..00000000
--- a/examples/with-apollo-auth/lib/withData.js
+++ /dev/null
@@ -1,103 +0,0 @@
-import React from 'react'
-import cookie from 'cookie'
-import PropTypes from 'prop-types'
-import { ApolloProvider, getDataFromTree } from 'react-apollo'
-import Head from 'next/head'
-
-import initApollo from './initApollo'
-
-function parseCookies(context = {}, options = {}) {
- return cookie.parse(
- context.req && context.req.headers.cookie
- ? context.req.headers.cookie
- : document.cookie,
- options
- )
-}
-
-export default ComposedComponent => {
- return class WithData extends React.Component {
- static displayName = `WithData(${ComposedComponent.displayName})`
- static propTypes = {
- serverState: PropTypes.object.isRequired
- }
-
- static async getInitialProps(context) {
- let serverState = {}
-
- // Setup a server-side one-time-use apollo client for initial props and
- // rendering (on server)
- let apollo = initApollo({}, {
- getToken: () => parseCookies(context).token
- })
-
- // Evaluate the composed component's getInitialProps()
- let composedInitialProps = {}
- if (ComposedComponent.getInitialProps) {
- composedInitialProps = await ComposedComponent.getInitialProps(context, apollo)
- }
-
- // Run all graphql queries in the component tree
- // and extract the resulting data
- if (!process.browser) {
- if (context.res && context.res.finished) {
- // When redirecting, the response is finished.
- // No point in continuing to render
- return
- }
-
- // Provide the `url` prop data in case a graphql query uses it
- const url = { query: context.query, pathname: context.pathname }
- try {
- // Run all GraphQL queries
- const app = (
-
-
-
- )
- await getDataFromTree(app, {
- router: {
- query: context.query,
- pathname: context.pathname,
- asPath: context.asPath
- }
- })
- } catch (error) {
- // Prevent Apollo Client GraphQL errors from crashing SSR.
- // Handle them in components via the data.error prop:
- // http://dev.apollodata.com/react/api-queries.html#graphql-query-data-error
- }
- // getDataFromTree does not call componentWillUnmount
- // head side effect therefore need to be cleared manually
- Head.rewind()
-
- // Extract query data from the Apollo's store
- serverState = apollo.cache.extract()
- }
-
- return {
- serverState,
- ...composedInitialProps
- }
- }
-
- constructor(props) {
- super(props)
- // Note: Apollo should never be used on the server side beyond the initial
- // render within `getInitialProps()` above (since the entire prop tree
- // will be initialized there), meaning the below will only ever be
- // executed on the client.
- this.apollo = initApollo(this.props.serverState, {
- getToken: () => parseCookies().token
- })
- }
-
- render() {
- return (
-
-
-
- )
- }
- }
-}
\ No newline at end of file
diff --git a/examples/with-apollo-auth/package.json b/examples/with-apollo-auth/package.json
index b9679686..d783be45 100644
--- a/examples/with-apollo-auth/package.json
+++ b/examples/with-apollo-auth/package.json
@@ -6,8 +6,7 @@
"scripts": {
"dev": "next",
"build": "next build",
- "start": "next start",
- "test": "NODE_ENV=test ava"
+ "start": "next start"
},
"dependencies": {
"apollo-boost": "^0.1.4",
@@ -20,16 +19,5 @@
"react": "^16.2.0",
"react-apollo": "^2.1.1",
"react-dom": "^16.2.0"
- },
- "devDependencies": {
- "ava": "^0.19.1",
- "clear-require": "^2.0.0",
- "glob": "^7.1.2"
- },
- "ava": {
- "require": [
- "babel-register"
- ],
- "babel": "inherit"
}
}
diff --git a/examples/with-apollo-auth/pages/_app.js b/examples/with-apollo-auth/pages/_app.js
new file mode 100644
index 00000000..bf3894cc
--- /dev/null
+++ b/examples/with-apollo-auth/pages/_app.js
@@ -0,0 +1,17 @@
+import App, { Container } from 'next/app'
+import React from 'react'
+import { ApolloProvider } from 'react-apollo'
+import withApollo from '../lib/withApollo'
+
+class MyApp extends App {
+ render () {
+ const { Component, pageProps, apolloClient } = this.props
+ return
+
+
+
+
+ }
+}
+
+export default withApollo(MyApp)
diff --git a/examples/with-apollo-auth/pages/create-account.js b/examples/with-apollo-auth/pages/create-account.js
index a5b59d3d..8894c70b 100644
--- a/examples/with-apollo-auth/pages/create-account.js
+++ b/examples/with-apollo-auth/pages/create-account.js
@@ -1,16 +1,14 @@
import React from 'react'
-import { compose } from 'react-apollo'
import Link from 'next/link'
-import withData from '../lib/withData'
import redirect from '../lib/redirect'
import checkLoggedIn from '../lib/checkLoggedIn'
import RegisterBox from '../components/RegisterBox'
-class CreateAccount extends React.Component {
- static async getInitialProps (context, apolloClient) {
- const { loggedInUser } = await checkLoggedIn(context, apolloClient)
+export default class CreateAccount extends React.Component {
+ static async getInitialProps (context) {
+ const { loggedInUser } = await checkLoggedIn(context.apolloClient)
if (loggedInUser.user) {
// Already signed in? No need to continue.
@@ -32,8 +30,3 @@ class CreateAccount extends React.Component {
)
}
};
-
-export default compose( // TODO: Maybe remove the usage of compose?
- // withData gives us server-side graphql queries before rendering
- withData
-)(CreateAccount)
diff --git a/examples/with-apollo-auth/pages/index.js b/examples/with-apollo-auth/pages/index.js
index eb1fd6f3..6b979f76 100644
--- a/examples/with-apollo-auth/pages/index.js
+++ b/examples/with-apollo-auth/pages/index.js
@@ -1,14 +1,13 @@
import React from 'react'
import cookie from 'cookie'
-import { withApollo, compose } from 'react-apollo'
+import { ApolloConsumer } from 'react-apollo'
-import withData from '../lib/withData'
import redirect from '../lib/redirect'
import checkLoggedIn from '../lib/checkLoggedIn'
-class Index extends React.Component {
+export default class Index extends React.Component {
static async getInitialProps (context, apolloClient) {
- const { loggedInUser } = await checkLoggedIn(context, apolloClient)
+ const { loggedInUser } = await checkLoggedIn(context.apolloClient)
if (!loggedInUser.user) {
// If not signed in, send them somewhere more useful
@@ -18,14 +17,14 @@ class Index extends React.Component {
return { loggedInUser }
}
- signout = () => {
+ signout = apolloClient => () => {
document.cookie = cookie.serialize('token', '', {
maxAge: -1 // Expire the cookie immediately
})
// 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.cache.reset().then(() => {
+ apolloClient.cache.reset().then(() => {
// Redirect to a more useful page when signed out
redirect({}, '/signin')
})
@@ -33,17 +32,14 @@ class Index extends React.Component {
render () {
return (
-
- Hello {this.props.loggedInUser.user.name}!
-
-
+
+ {client => (
+
+ Hello {this.props.loggedInUser.user.name}!
+
+
+ )}
+
)
}
};
-
-export default compose(
- // withData gives us server-side graphql queries before rendering
- withData,
- // withApollo exposes `this.props.client` used when logging out
- withApollo
-)(Index)
diff --git a/examples/with-apollo-auth/pages/signin.js b/examples/with-apollo-auth/pages/signin.js
index e0397651..65cb5aa3 100644
--- a/examples/with-apollo-auth/pages/signin.js
+++ b/examples/with-apollo-auth/pages/signin.js
@@ -1,16 +1,14 @@
import React from 'react'
-import { compose } from 'react-apollo'
import Link from 'next/link'
-import withData from '../lib/withData'
import redirect from '../lib/redirect'
import checkLoggedIn from '../lib/checkLoggedIn'
import SigninBox from '../components/SigninBox'
-class Signin extends React.Component {
- static async getInitialProps (context, apolloClient) {
- const { loggedInUser } = await checkLoggedIn(context, apolloClient)
+export default class Signin extends React.Component {
+ static async getInitialProps (context) {
+ const { loggedInUser } = await checkLoggedIn(context.apolloClient)
if (loggedInUser.user) {
// Already signed in? No need to continue.
@@ -32,8 +30,3 @@ class Signin extends React.Component {
)
}
};
-
-export default compose( // TODO: Maybe remove the usage of compose?
- // withData gives us server-side graphql queries before rendering
- withData
-)(Signin)
diff --git a/examples/with-apollo-auth/test/shared-apollo.js b/examples/with-apollo-auth/test/shared-apollo.js
deleted file mode 100644
index 07e6451e..00000000
--- a/examples/with-apollo-auth/test/shared-apollo.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const clearRequire = require('clear-require')
-const glob = require('glob')
-const test = require('ava')
-
-/**
- * Motivations:
- *
- * - Client-side getInitialProps() wont have access to the apollo client for
- * that page (because it's not shared across page bundles), so wont be able to
- * reset the state, leaving all the logged in user data there :(
- * - So, we have to have a shared module. BUT; next's code splitting means the
- * bundle for each page will include its own copy of the module, _unless it's
- * included in every page_.
- * - https://github.com/zeit/next.js/issues/659#issuecomment-271824223
- * - https://github.com/zeit/next.js/issues/1635#issuecomment-292236785
- * - Therefore, this test ensures that every page includes that module, and
- * hence it will be shared across every page, giving us a global store in
- * Apollo that we can clear, etc
- */
-
-const apolloFilePath = require.resolve('../lib/initApollo')
-
-test.beforeEach(() => {
- // Clean up the cache
- clearRequire.all()
-})
-
-glob.sync('./pages/**/*.js').forEach((file) => {
- test(`.${file} imports shared apollo module`, (t) => {
- t.falsy(require.cache[apolloFilePath])
-
- try {
- require(`.${file}`)
- } catch (error) {
- // Don't really care if it fails to execute, etc, just want to be
- // certain the expected require call was made
- }
-
- t.truthy(require.cache[apolloFilePath])
- })
-})