Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

(next-urql) - add example of using the built-in data-fetching functions (#1168)

* add example of using the data-fetching functions of next.js

* prevent undefined from slipping into the serializedresult

* add changeset

* adjust docs

* Update .changeset/curvy-terms-dress.md

Co-authored-by: Phil Pluckthun <phil@kitten.sh>

* Update packages/core/src/exchanges/ssr.ts

Co-authored-by: Phil Pluckthun <phil@kitten.sh>

Co-authored-by: Phil Pluckthun <phil@kitten.sh>

authored by

Jovi De Croock
Phil Pluckthun
and committed by
GitHub
c0fe56a9 a71bfea4

+77 -5
+5
.changeset/curvy-terms-dress.md
··· 1 + --- 2 + '@urql/core': patch 3 + --- 4 + 5 + Don't add `undefined` to any property of the `ssrExchange`'s serialized results, as this would crash in Next.js
+63
docs/advanced/server-side-rendering.md
··· 246 246 During the prepass of your component tree `next-urql` can't know how these functions will alter the props passed to your page component. This injection 247 247 could change the `variables` used in your `useQuery`. This will lead to error being thrown during the subsequent `toString` pass, which isn't supported in React 16. 248 248 249 + ### Using getStaticProps or getServerSideProps 250 + 251 + By default `withUrqlClient` will add `getInitialProps` to the component you're wrapping it in, this however excludes us from using 252 + `getStaticProps` and `getServerSideProps`. However we can enable this, let's look at an example: 253 + 254 + ```js 255 + import { withUrqlClient, initUrqlClient } from "next-urql"; 256 + import { 257 + ssrExchange, 258 + dedupExchange, 259 + cacheExchange, 260 + fetchExchange, 261 + useQuery 262 + } from "urql"; 263 + 264 + const TODOS_QUERY = ` 265 + query { todos { id text } } 266 + `; 267 + 268 + const createUrqlClient = (ssr, ctx) => ({ 269 + url: "your-url" 270 + exchanges: [dedupExchange, cacheExchange, ssrCache, fetchExchange] 271 + }); 272 + 273 + function Todos() { 274 + const [res] = useQuery({ query: TODOS_QUERY }); 275 + return ( 276 + <div> 277 + {res.data.todos.map((todo) => ( 278 + <div key={todo.id}> 279 + {todo.id} - {todo.text} 280 + </div> 281 + ))} 282 + </div> 283 + ); 284 + } 285 + 286 + export async function getStaticProps(ctx) { 287 + const ssrCache = ssrExchange({ isClient: false }); 288 + const client = initUrqlClient(createUrqlClient(ssrCache, ctx)); 289 + 290 + // This query is used to populate the cache for the query 291 + // used on this page. 292 + await client.query(TODOS_QUERY).toPromise(); 293 + 294 + return { 295 + props: { 296 + // urqlState is a keyword here so withUrqlClient can pick it up. 297 + urqlState: ssrCache.extractData() 298 + }, 299 + }; 300 + } 301 + 302 + export default withUrqlClient( 303 + createUrqlClient, 304 + { ssr: false } // Important so we don't wrap our component in getInitialProps 305 + )(Todos); 306 + ``` 307 + 308 + The above example will make sure the page is rendered as a static-page, it's important that you fully pre-populate your cache 309 + so in our case we were only interested in getting our todos, if there are child components relying on data you'll have to make 310 + sure these are fetched as well. 311 + 249 312 ### Resetting the client instance 250 313 251 314 In rare scenario's you possibly will have to reset the client instance (reset all cache, ...), this is an uncommon scenario
+9 -5
packages/core/src/exchanges/ssr.ts
··· 35 35 data, 36 36 error, 37 37 }: OperationResult): SerializedResult => { 38 - const result: SerializedResult = { 39 - data: JSON.stringify(data), 40 - error: undefined, 41 - }; 38 + const result: SerializedResult = {}; 39 + 40 + if (data !== undefined) { 41 + result.data = JSON.stringify(data); 42 + } 42 43 43 44 if (error) { 44 45 result.error = { ··· 51 52 extensions: error.extensions, 52 53 }; 53 54 }), 54 - networkError: error.networkError ? '' + error.networkError : undefined, 55 55 }; 56 + 57 + if (error.networkError) { 58 + result.error.networkError = '' + error.networkError; 59 + } 56 60 } 57 61 58 62 return result;