Example name is with-apollo-auth
I implemented the with-apollo-auth example. See this repo.
Every query is now Server Side Rendered using getDataFromTree, but... not one query. The me query, that is based on authentication cookie doesn't work at all.
When I didn't use the example and was happy with Client Side Rendering, the cookie and me query rendered properly. But, on SSR... backend doesn't look like is sending any cookie.
Here's the complete backend repo.
https://paprink-server.herokuapp.com the endpoint.me query.loggedInUser be undefined.The expected behaviour was to see the paprinkToken cookie being parsed.
v8.1.0Have you tried the example? I saw the example uses graphcool but it isn't clear about how you get the cookie.
Experiencing the same issue
Would appreciate an investigation of the issue posted 馃憤
I've marked it as good first issue. There is no need to keep pinging on open issues.
with-apollo-auth example wasn't working... so to cater the needs...
Harshit Pant helped me by writing this code.
init-apollo.js 馃憞
import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { HttpLink } from 'apollo-link-http'
import { ApolloLink } from 'apollo-link'
import { onError } from 'apollo-link-error'
import { setContext } from 'apollo-link-context'
import fetch from 'isomorphic-unfetch'
// import { WebSocketLink } from 'apollo-link-ws'
// import { getMainDefinition } from 'apollo-utilities'
const httpLink = new HttpLink({
uri: `${process.env.ENDPOINT}/api/graphql`,
credentials: 'include',
})
const cache = new InMemoryCache()
let link = null
if (process.browser) {
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) =>
// tslint:disable-next-line:no-console
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
)
}
if (networkError) {
// tslint:disable-next-line:no-console
console.log(`[Network error]: ${networkError}`)
}
})
link = ApolloLink.from([errorLink, httpLink])
}
let apolloClient = null
// Polyfill fetch() on the server (used by apollo-client)
if (!process.browser) {
global.fetch = fetch
}
function create(initialState, cookie = null) {
const authLink = setContext((_, { headers }) => {
return {
headers: {
...headers,
Cookie: cookie,
},
}
})
return new ApolloClient({
connectToDevTools: process.browser,
ssrMode: !process.browser, // Disables forceFetch on the server (so queries are only run once)
link: process.browser ? link : authLink.concat(httpLink),
cache: cache.restore(initialState || {}),
})
}
export default function initApollo(initialState, cookie) {
// 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 (!process.browser) {
return create(initialState, cookie)
}
// Reuse client on the client-side
if (!apolloClient) {
apolloClient = create(initialState)
}
return apolloClient
}
with-apollo-client.js 馃憞
import React from "react";
import initApollo from "./init-apollo";
import Head from "next/head";
import { getDataFromTree } from "react-apollo";
export default App => {
return class Apollo extends React.Component {
static displayName = "withApollo(App)";
static async getInitialProps(ctx) {
const { Component, router } = ctx;
let appProps = {};
if (App.getInitialProps) {
appProps = await App.getInitialProps(ctx);
}
const apolloState = {};
const apollo = !process.browser
? initApollo(null, ctx.ctx.req.headers.cookie)
: initApollo();
// Run all GraphQL queries in the component tree
// and extract the resulting data
try {
// Run all GraphQL queries
await getDataFromTree(
<App
{...appProps}
Component={Component}
router={router}
apolloState={apolloState}
apolloClient={apollo}
/>
);
} 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 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);
}
render() {
return <App {...this.props} apolloClient={this.apolloClient} />;
}
};
};
_app.js 馃憞
import React from 'react'
import App, { Container } from 'next/app'
import { ApolloProvider } from 'react-apollo'
import withData from '../src/lib/with-apollo-client'
import Page from '../src/components/Page'
class Wrapper extends App {
static async getInitialProps({Component, ctx}){
let pageProps = {}
if(Component.getInitialProps){
pageProps = await Component.getInitialProps(ctx)
}
// This exposes query to the user
pageProps.query = ctx.query
return { pageProps }
}
render() {
const { Component, apolloClient, pageProps } = this.props
return (
<Container>
<ApolloProvider client={apolloClient}>
<Page>
<div className="super_container"><Component {...pageProps} /></div>
</Page>
</ApolloProvider>
</Container>
)
}
}
export default withData(Wrapper)
That code, somehow similar to yours... implements the same thing differently which allows cookies to be rendered.
Here's the complete code for you to follow on and change with-apollo-auth example.
I'm quite confused with this issue - it doesn't seem to target with-apollo-auth example but focuses on the problem you have in application. I also see the error that there's no user which isn't surprising given I haven't made account yet. Are you sure you're correctly sending cookie to backend. The code you've provided seem to take a different approach at parsing cookies.
The thing is - I'm still not sure what's wrong with the example.
As far as example alone I keep on receiving issue that 'net' module is not found for https-proxy-agent. I'm not sure if I should create separate issue or do it here?
I'll close this because it sounds like OP solved their issue. @masives, please open a separate issue or PR for that! 馃檹
Hey @masives, the problem is that cookie won't render even after the signup... And in the example, there is no reference of how signin takes place.
Most helpful comment
Experiencing the same issue