I'm getting this error on initial load of my SSR application:
Warning: Text content did not match. Server: "SOME DATA" Client: "Loading..."
How to initialize client side of the app without setting loading
flag to true?
I’m setting up a SSR with react, express and apollo. I get a properly rendered HTML with data from the renderer server, but when client bundle loads up it’s trying to refetch data. Hydration is set up and all the data from renderer server is injected into the HTML of the page.
/index.js
<Query query={GET_USERS} variables={queryVariables}>
{({
loading,
error,
data
}) => {
if (loading) return <p>Loading...</p>;
if (error) return `Error: ${error}`;
return data.users.map(user => <p key={user.id}>{user.login}</p>);
}}
</Query>
/renderer.js
export default async (req, client) => {
const serverSideApp = (
<ApolloProvider client={client}>
<StaticRouter location={req.path} context={{}}>
<div>{renderRoutes(RoutesList)}</div>
</StaticRouter>
</ApolloProvider>
);
return getDataFromTree(serverSideApp).then(() => {
const content = renderToString(serverSideApp);
return `
<html>
<head></head>
<body>
<div id="root">${content}</div>
<script src="bundle.js"></script>
<script>
window.__APOLLO_STATE__=${serialize(client.extract())}
</script>
</body>
</html>
`;
})
};
/server.js
const app = express();
app.use(express.static("public"));
app.get("*", (req, res) => {
const httpLink = createHttpLink({
uri: "http://10.10.10.139:4000/",
fetch
});
const client = new ApolloClient({
link: httpLink,
ssrMode: true,
cache: new InMemoryCache()
});
renderer(req, client).then((html) => res.send(html));
});
app.listen(3000, () => {
console.log("Server is up");
});
/client.js
const httpLink = createHttpLink({
uri: "http://10.10.10.139:4000/"
});
const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache().restore(window.__APOLLO_STATE__)
});
ReactDOM.hydrate(
<ApolloProvider client={client}>
<BrowserRouter>
<div>{renderRoutes(RoutesList)}</div>
</BrowserRouter>
</ApolloProvider>,
document.getElementById("root")
);
I expect client side of the app rehydrate server side values and not to trigger loading
flag on initial load.
If using nextjs w/ styled-jsx
https://github.com/vercel/styled-jsx this error can occur if you omit the jsx
attribute on the style
tag.
Good (jsx
attribute is required):
<style jsx>{`...`}</style>
Bad (omit jsx
attribute):
<style>{`...`}</style>
Omitting the jsx
attr will throw following in browser Console:
react-dom.development.js Warning: Text content did not match. Server: "..." Client: "..."
From react-apollo
documentation, the Skipping queries for SSR section introduces a mechanism that allows developers to explicitly mark a component so that it either loads data for that component on the server or renders the component on the server in a 'loading' state.
Try the following:
// index.js
<Query query={GET_USERS} ssr={false} variables={queryVariables}>
{({
loading,
error,
data
}) => {
if (loading) return <p>Loading...</p>;
if (error) return `Error: ${error}`;
return data.users.map(user => <p key={user.id}>{user.login}</p>);
}}
</Query>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With