[{"data":1,"prerenderedAt":221},["ShallowReactive",2],{"DefaultLayouten":3,"language-blog-slug-componentize-data-with-graphql-fragments-i18n-slugs":134,"language-blog-slug-en-componentize-data-with-graphql-fragments":138},{"app":4,"menu":31,"footer":66},{"githubUrl":5,"youtubeUrl":6,"linkedinUrl":7,"phoneNumber":8,"emailAddress":9,"legal":10,"addresses":20},"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002F","https:\u002F\u002Fwww.youtube.com\u002Fchannel\u002FUCzHuhQVYFRixtQN2-swcuGg","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fde-voorhoede","+31 20 2610 954","post@voorhoede.nl",[11,14,17],{"title":12,"value":13},"KvK","56017235",{"title":15,"value":16},"BTW","NL851944620B01",{"title":18,"value":19},"IBAN","NL14TRIO0320142078",[21,26],{"address":22,"city":23,"googleMapsLink":24,"postalCode":25},"Koivistokade 70","Amsterdam","https:\u002F\u002Fwww.google.com\u002Fmaps\u002Fplace\u002FDe+Voorhoede+%7C+Front-end+Development\u002F@52.396847,4.8700823,17z\u002Fdata=!3m1!4b1!4m5!3m4!1s0x47c5e21d502d2d59:0xbf570944a96ebf45!8m2!3d52.347647!4d4.8502154","1013 BB",{"address":27,"city":28,"googleMapsLink":29,"postalCode":30},"Koornmarkt 22","Delft","https:\u002F\u002Fwww.google.nl\u002Fmaps\u002Fplace\u002FKoornmarkt+22,+2611+EG+Delft\u002F@52.0093477,4.3573054,17z\u002F","2611 EG",{"title":32,"callToActions":33,"links":39},"Site Menu",[34],{"id":35,"title":36,"link":37},"163140902","Contact",{"__typename":38},"ContactRecord",[40,46,51,56,61],{"id":41,"title":42,"link":43},"163140904","Impact",{"__typename":44,"slug":45},"PageRecord","impact",{"id":47,"title":48,"link":49},"163140905","Services",{"__typename":50},"ServiceOverviewRecord",{"id":52,"title":53,"link":54},"163140906","Cases",{"__typename":55},"CaseOverviewRecord",{"id":57,"title":58,"link":59},"163140908","About us",{"__typename":44,"slug":60},"about-us",{"id":62,"title":63,"link":64},"d6WdFJq2SOuc3dWtpibbXQ","Work at",{"__typename":44,"slug":65},"work-at",{"links":67,"copyrightTitle":93,"copyrightLabel":94,"copyrightLink":95,"privacyTitle":96,"privacyLabel":97,"privacyLink":98,"certificatesGrid":99},[68,71,74,77,82,85,88],{"id":69,"title":42,"link":70},"144185264",{"__typename":44,"slug":45},{"id":72,"title":48,"link":73},"144185265",{"__typename":50},{"id":75,"title":53,"link":76},"144185266",{"__typename":55},{"id":78,"title":79,"link":80},"144185267","Blog",{"__typename":81},"BlogPostOverviewRecord",{"id":83,"title":58,"link":84},"144185268",{"__typename":44,"slug":60},{"id":86,"title":36,"link":87},"144185269",{"__typename":38},{"id":89,"title":90,"link":91},"144185270","FAQ",{"__typename":44,"slug":92},"faq","Creative Commons licence and disclaimer","CC BY 4.0","https:\u002F\u002Fcreativecommons.org\u002Flicenses\u002Fby\u002F4.0\u002F","De Voorhoede privacy statement (pdf)","Privacy statement","https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1763455455-vh-isms-006-privacy-statement-de-voorhoede-en.pdf",[100,112,123],{"id":101,"image":102,"link":107},"Xq4bBfg_TZ6Fkjax9mkbLQ",{"url":103,"alt":104,"width":105,"height":106},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1687353463-b-corp-logo-black-rgb.png","B Corp logo",404,680,{"__typename":108,"id":109,"title":110,"url":111},"ExternalLinkRecord","fGW1ak8XQYaYDLkBSyncog","B Corp","https:\u002F\u002Fwww.bcorporation.net\u002Fen-us\u002Ffind-a-b-corp\u002Fcompany\u002Fde-voorhoede\u002F",{"id":113,"image":114,"link":119},"c5mCXRTiSraRIB25fw1p7Q",{"url":115,"alt":116,"width":117,"height":118},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1687353461-dda-boxlogo-black.png","Dutch Digital Agencies logo",627,480,{"__typename":108,"id":120,"title":121,"url":122},"P6Jh7B0cTv2cKyNEeKVWVQ","Dutch Digital Agencies","https:\u002F\u002Fdutchdigitalagencies.com\u002Fleden\u002Fde-voorhoede\u002F",{"id":124,"image":125,"link":129},"MT5SCyNxSTSr_v5eeATMZw",{"url":126,"alt":127,"width":128,"height":128},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1775730283-dnv.png","DNV logo",518,{"id":130,"title":131,"link":132},"BRtNB5HnT5i-7HkA8IYzBw","DIV",{"__typename":44,"slug":133},"impact\u002Fdigitale-producten-privacy-by-design",[135],{"locale":136,"value":137},"en","componentize-data-with-graphql-fragments",{"page":139},{"slug":137,"i18nSlugs":140,"social":142,"title":143,"subtitle":79,"isArchived":146,"headerIllustration":145,"date":147,"authors":148,"introTitle":157,"items":158,"pivots":218,"relatedBlogPosts":219,"tags":220,"onMountedScript":151,"onUnmountedScript":151},[141],{"locale":136,"value":137},{"title":143,"description":144,"image":145},"Componentize data with GraphQL Fragments","By separating GraphQL fragments into separate files you can fully componentize your data and bundle them with your React or Vue  components. Read how.",null,false,"2021-10-01T02:00:00.000+02:00",[149],{"name":150,"lastName":151,"slug":152,"image":153},"Jasper","","jasper",{"url":154,"alt":145,"width":155,"height":156},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1683535518-jasper.jpg",1892,2523,"GraphQL offers fragments - reusable units of logic that can be shared between multiple queries and mutations. By separating GraphQL fragments into separate files you can fully componentize your data and bundle them with your React or Vue (or any other flavour) components.",[159,164,169,172,175,178,182,186,189,192,195,198,201,205,209,212,215],{"__typename":160,"id":161,"title":162,"body":163},"TextSectionRecord","61952883"," GraphQL fragments: reusable units","\u003Cp>The easiest way to explain \u003Ca href=\"https:\u002F\u002Fgraphql.org\u002Flearn\u002Fqueries\u002F#fragments\">GraphQL fragments\u003C\u002Fa> is with a quick example. When you have repeating logic, like the \u003Ccode>image\u003C\u002Fcode> in this query:\u003C\u002Fp>",{"__typename":165,"id":166,"language":167,"body":168},"CodeBlockRecord","61952884","graphql","query {\n  posts {\n    title\n    image {\n      alt, src, width, height, filetype, base64\n    }\n    authors {\n      name\n      image {\n        alt, src, width, height, filetype, base64\n      }\n    }\n  }\n}",{"__typename":160,"id":170,"title":151,"body":171},"61952885","\u003Cp>You can turn that repeating image logic into a fragment:\u003C\u002Fp>",{"__typename":165,"id":173,"language":167,"body":174},"61952886","query Blog {\n  posts {\n    title\n    image { ...imageFragment }\n    authors {\n      name\n      image { ...imageFragment }\n    }\n  }\n}\n\nfragment imageFragment on Image {\n  alt\n  src\n  width\n  height\n  filetype\n  base64\n}",{"__typename":160,"id":176,"title":151,"body":177},"61952887","\u003Cp>\u003Cspan>This makes the image logic more reusable within this file. But what if we want to use this fragment in other files? And how can you bundle fragments with other component files?\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":160,"id":179,"title":180,"body":181},"61952888"," Fragment files for component data","\u003Cp>\u003Cspan>We can move our GraphQL fragments to their own files and (with the help of a bit of tooling) import them where we need. As a convention we use a \u003C\u002Fspan>\u003Ccode>.fragment.graphql\u003C\u002Fcode>\u003Cspan> extension for our fragments and \u003C\u002Fspan>\u003Ccode>.query.graphql\u003C\u002Fcode>\u003Cspan> for files containing our GraphQL queries. This allows us to bundle our GraphQL fragments with components and put queries along our pages (or routes). In a typical React or Vue flavoured project our file structure looks something like this:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":165,"id":183,"language":184,"body":185},"61952889","bash","components\u002F\n  Image.(jsx|vue)\n  Image.fragment.graphql\n\npages\u002F\n  Blog.(jsx|vue)\n  Blog.query.graphql",{"__typename":160,"id":187,"title":151,"body":188},"61952890","\u003Cp>Where \u003Ccode>Image.fragment.graphql\u003C\u002Fcode>:\u003C\u002Fp>",{"__typename":165,"id":190,"language":167,"body":191},"61952891","fragment imageFragment on Image {\n  alt\n  src\n  width\n  height\n  filetype\n  base64\n}",{"__typename":160,"id":193,"title":151,"body":194},"61952892","\u003Cp>\u003Cspan>And \u003C\u002Fspan>\u003Ccode>Blog.query.graphql\u003C\u002Fcode>\u003Cspan>:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":165,"id":196,"language":167,"body":197},"61952893","#import '..\u002Fcomponents\u002FImage.fragment.graphql'\n\nquery Blog($locale: SiteLocale) {\n  posts {\n    title\n    image { ...imageFragment }\n    authors {\n      name\n      image { ...imageFragment }\n    }\n  }\n}",{"__typename":160,"id":199,"title":151,"body":200},"61952894","\u003Cp>The result is a clear and maintainable setup using GraphQL in our project.\u003C\u002Fp>",{"__typename":160,"id":202,"title":203,"body":204},"61952895","Importing GraphQL files","\u003Cp>\u003Cspan>As noted earlier, being able to import our GraphQL fragments into other GraphQL files does require a bit of tooling. The \u003C\u002Fspan>\u003Ccode>#import '&hellip;\u002FImage.fragment.graphql'\u003C\u002Fcode>\u003Cspan> syntax above is not built-in GraphQL syntax. The GraphQL specification does not provide anything to declare or resolve such dependencies. So instead we use tooling for this. In our example we&rsquo;re relying on the \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fwebpack-graphql-loader\">\u003Ccode>webpack-graphql-loader\u003C\u002Fcode>\u003C\u002Fa>\u003Cspan> which enables the import syntax in GraphQL files (\u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fgraphql-tag#user-content-importing-graphql-files\">\u003Ccode>graphql-tag\u003C\u002Fcode>\u003C\u002Fa>\u003Cspan> is a good alternative). We configure the loader for our \u003C\u002Fspan>\u003Ccode>.grapqhl\u003C\u002Fcode>\u003Cspan> files in our Webpack setup:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":165,"id":206,"language":207,"body":208},"61952896","js","webpackConfig.module.rules.push({\n  test: \u002F\\.graphql?$\u002F,\n  loader: 'webpack-graphql-loader'\n})",{"__typename":160,"id":210,"title":151,"body":211},"61952897","\u003Cp>\u003Cspan>The loader also allows us to directly load GraphQL files in JavaScript files, so we can use the queries to fetch data. For example in a Next.js app:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":165,"id":213,"language":207,"body":214},"61952898","\u002F\u002F pages\u002FBlog.jsx\nimport { graphqlRequest } from '..\u002Flib\u002Four-graphql-request-helper'\nimport query from '.\u002FBlog.query.graphql'\n\nexport async function getStaticProps({ locale }) {\n  const { posts } = await graphqlRequest({\n    query,\n    variables: { locale },\n  })\n  return { props: { posts } }\n}",{"__typename":160,"id":216,"title":151,"body":217},"61952899","\u003Cp>\u003Cspan>That&rsquo;s it. Have fun componentizing your GraphQL.\u003C\u002Fspan>\u003C\u002Fp>",[],[],[],1776256144007]