{"id":5589,"date":"2023-10-19T09:26:44","date_gmt":"2023-10-19T14:26:44","guid":{"rendered":"https:\/\/wpengine.com\/builders\/?p=5589"},"modified":"2023-11-13T11:40:01","modified_gmt":"2023-11-13T17:40:01","slug":"next-js-13-and-wpgraphql-in-headless-wordpress","status":"publish","type":"post","link":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/","title":{"rendered":"Next.js 13 and WPGraphQL in headless WordPress"},"content":{"rendered":"\n<p>In this article, you will learn how to create a simple headless WordPress app using <a href=\"https:\/\/developers.wpengine.com\/docs\/glossary#next-js\">Next.js<\/a> 13 and <a href=\"https:\/\/developers.wpengine.com\/docs\/glossary#wpgraphql\">WPGraphQL<\/a>. This tutorial assumes a basic understanding of <a href=\"https:\/\/developers.wpengine.com\/docs\/glossary#react\">React<\/a> , Next.js 12, and WordPress. Using the prepared GitHub repository will allow us to focus on points specific to Next.js 13 and some of its new features.&nbsp; By the end of this tutorial, you will be able to understand:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The App router&nbsp;<\/li>\n\n\n\n<li>Roles of Folders and Files in the new App Router<\/li>\n\n\n\n<li>File Conventions in the new App Router<\/li>\n\n\n\n<li>Default React Server Components in Next.js 13<\/li>\n\n\n\n<li>Adding WPGraphQL Queries \/ Data Fetching<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Getting Started<\/h2>\n\n\n\n<p>To get started, you\u2019ll need to make sure that you have both <a href=\"https:\/\/nodejs.org\/en\/\">Node.js<\/a> and <a href=\"https:\/\/docs.npmjs.com\/downloading-and-installing-node-js-and-npm\">npm<\/a> installed.&nbsp; In order to make this work, you need to be on Node.js 16.14 or later. If you aren\u2019t sure whether or not you have this software installed, you can run the following commands in your terminal:<\/p>\n\n\n\n<p><code>\u200b\u200bnode -v<\/code><\/p>\n\n\n\n<p><code>npm -v<\/code><\/p>\n\n\n\n<p>The terminal output should either tell you which versions you have installed or that it cannot find the commands node or npm to run them. Using <a href=\"https:\/\/github.com\/nvm-sh\/nvm\">a tool like nvm (Node Version Manager)<\/a> to install and manage versions of Node.js on your machine can be helpful when working on multiple projects.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Configure Your WordPress Site<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Set up a WordPress site on Local, WP Engine, or any host of your choice<\/li>\n\n\n\n<li>Install and activate the WPGraphQL plugin.&nbsp; Activate debug mode for it:<\/li>\n<\/ol>\n\n\n\n<div class=\"wp-block-group has-base-color has-text-color has-background has-link-color wp-elements-688844c5591b0d750f2228c71fe3f5ec has-global-padding is-layout-constrained wp-container-core-group-is-layout-c825ac28 wp-block-group-is-layout-constrained\" style=\"border-radius:12px;background-color:#180038;margin-bottom:var(--wp--preset--spacing--30);padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)\">\n<div class=\"wp-block-group alignwide is-content-justification-left is-layout-flex wp-container-core-group-is-layout-682063c7 wp-block-group-is-layout-flex\" style=\"padding-top:0;padding-right:0;padding-bottom:0;padding-left:0\">\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-e4830150 wp-block-group-is-layout-flex\">\n<div class=\"wp-block-outermost-icon-block\"><div class=\"icon-container\" style=\"width:38px\"><svg fill=\"none\" viewBox=\"0 0 38 30\" aria-label=\"Frost logo\"><path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M18.149.498c-.043.01-.16.025-.259.033-.406.03-.933.112-1.53.238-.205.043-.769.198-.98.269-.114.039-.574.207-.618.226l-.292.124c-.3.128-.74.346-1.01.502a4.92 4.92 0 0 1-.206.115 10.57 10.57 0 0 0-4.878 6.728c-.018.106-.035.118-.237.165-.17.039-.23.055-.54.147C3.36 10.302.453 13.9.037 18.401c-.045.49-.05 8.792-.006 9.065.18 1.094.97 1.87 2.052 2.012.375.049 4.136.05 4.527.002 1.185-.148 2.032-1.046 2.102-2.228.055-.925.614-1.62 1.403-1.745.29-.046.37-.05.528-.022.905.158 1.437.76 1.5 1.7.083 1.249.888 2.135 2.084 2.294.363.048 4.162.048 4.518 0 .633-.086 1.262-.421 1.616-.862l.124-.154c.13-.156.29-.575.341-.885.046-.277.047-8.617.002-8.907-.183-1.17-1.208-1.979-2.505-1.979-.386 0-1.057-.13-1.593-.306a5.82 5.82 0 0 1-3.868-4.496c-.16-.907-.112-1.586.187-2.655.417-1.494 1.717-2.941 3.22-3.585l.158-.068c.28-.121.809-.268 1.214-.336a5.03 5.03 0 0 1 1.98.042c2.288.53 3.911 2.078 4.476 4.272.198.768.189.427.19 7.436.002 3.432.012 6.28.023 6.399.304 3.24 2.565 5.63 5.713 6.037.829.107 1.116.107 1.8-.001 2.037-.322 3.807-1.829 4.698-4.001l.046-.112c.148-.36.347-1.107.407-1.53.119-.823.073-1.372-.15-1.817-.255-.508-.802-.924-1.493-1.137-.253-.078-.998-.08-1.2-.005-.026.01-.11.037-.183.06-.666.202-1.24.854-1.493 1.696-.03.101-.093.523-.093.63 0 .044-.02.162-.046.26-.44 1.724-2.917 1.715-3.316-.013-.03-.128-.034-.905-.034-6.275 0-6.296-.005-6.684-.089-7.276a11.333 11.333 0 0 0-.114-.742c-.012-.05-.042-.186-.066-.304-.734-3.596-3.431-6.625-6.951-7.805a9.125 9.125 0 0 0-.855-.246 7.503 7.503 0 0 0-.888-.179 18.617 18.617 0 0 0-.877-.117c-.28-.033-.874-.046-.977-.02Zm-.047 8.132c-1.224.212-1.998 1.382-1.8 2.72.027.186.034.213.115.462.554 1.717 3.03 1.998 3.992.452.055-.088.1-.165.1-.172 0-.006.025-.064.056-.128.131-.27.214-.68.214-1.052 0-1.52-1.194-2.539-2.677-2.282Zm-9.55 5.116c.577 2.153 2.094 4.3 3.988 5.648.78.554 1.328.849 2.38 1.28.077.031.556.195.675.23l.247.07.236.069.101.03.006 1.66c.006 1.695.002 1.779-.078 1.615-.772-1.58-2.366-2.836-4.134-3.256-.626-.149-.883-.178-1.552-.178-2.132.001-4.114 1.027-5.234 2.711-.17.254-.36.57-.412.686-.101.22-.1.256-.1-2.611 0-3 .005-3.148.129-3.748a5.873 5.873 0 0 1 1.94-3.294 5.92 5.92 0 0 1 1.518-.927c.222-.091.262-.09.29.015Z\" clip-rule=\"evenodd\"><\/path><\/svg><\/div><\/div>\n\n\n\n<p class=\"has-large-font-size\" style=\"font-style:normal;font-weight:800;letter-spacing:-1px\">WPGraphQL<\/p>\n<\/div>\n\n\n\n<p class=\"has-small-font-size wp-container-content-c86e52ed\" style=\"line-height:1.5\">An extendable GraphQL <br>schema &amp; API for WordPress.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-horizontal is-content-justification-center is-nowrap is-layout-flex wp-container-core-buttons-is-layout-3bdbf2e2 wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button is-style-outline-base\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/wpeng.in\/wpgraphql-builders\/\" style=\"border-radius:99px;padding-top:10px;padding-right:24px;padding-bottom:10px;padding-left:24px\" target=\"_blank\" rel=\"noreferrer noopener\">Download<\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/PqxqlVI7vwv-2dkMtiNeJlcWhDoiQjJFFzYMkRkbzIGlF5uYiPUAH2S46kUkQf4VIgerM-mjJ7lQzLVauRljc86phK6GMDHdAh9Uc8cNRhdqNrvzdEgR-cu7hxg_nEzNcJt5MzE0Z359ziVfa3MTNjI\" width=\"624\" height=\"292\"><\/p>\n\n\n\n<p>To activate Debug Mode open the <code>GraphQL &gt; Settings<\/code> menu and check the option labeled <code>Enable GraphQL Debug Mode<\/code> and then click <code>Save Changes.<\/code><\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/KQluIeTPfDhQMgx5MlhRhD9x1rEZEFhzPupzKZKfz-2djotjRLV0mJmW_OgtaAUGfbsXzn7K6pFcq5uQEsZHr-_sR9bMn8RCHdtfDc30Dor0FDKjhp1BKgFPHhXI1XvDIvEYHdgq7xU6BhrcbQweaEc\" width=\"624\" height=\"243\"><\/p>\n\n\n\n<p>3.Check Permalink Settings:<\/p>\n\n\n\n<p>All of the code in this article assumes that you have the <code>Post name<\/code> option selected for your permalink settings. To check or modify this setting, open the <code>Settings &gt; Permalinks<\/code> menu in the WP Admin dashboard.<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"299\" src=\"https:\/\/lh4.googleusercontent.com\/IL9eSxqOPe2THw-MzPUjBmS-MOwZxrBoWrqRCjmbJS8JysAAD_hCMHu7ybz9zrcYZ9NLRKll1XZzJbwD0UgT6TZe-9y1ck99wmbMMLgRFZ6VCqUyLdloq3aGn3K7Hpm__E9qvSlDeM2xFkYd9vkc2AY\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Create 5 Posts<\/strong><\/h3>\n\n\n\n<p>Make sure to create content for 5 posts on your WordPress site.&nbsp; We will be querying for the first 5 posts from WPGraphQL.&nbsp; I am a bit of a Star Wars nerd so I created some Star Wars content.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Next.js 13 Setup<\/strong><\/h2>\n\n\n\n<p>We now have our WordPress backend configured.&nbsp; Let\u2019s get stoked on setting up our Next.js 13 front-end.<\/p>\n\n\n\n<p>The rest of this tutorial is based on the files that can be found in <a href=\"https:\/\/github.com\/Fran-A-Dev\/nextjs13-headlesswp-example\">my GitHub repository<\/a>. This repository is based on <a href=\"https:\/\/nextjs.org\/docs\/api-reference\/create-next-app\">the default Next.js template<\/a> created with <code>create-next-app@latest<\/code> CLI tool, with some additional scaffolding and styles I added on my own using <a href=\"https:\/\/tailwindcss.com\/\">the Tailwind CSS utility framework.<\/a><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Clone down the repo locally, CD into that directory, and run <code>npm run install<\/code>.<\/li>\n\n\n\n<li>In the root of the project, create a <code>.env.local<\/code> file and add the following key and the value:&nbsp;&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<p><\/p>\n\n\n\n<p><code>NEXT_PUBLIC_GRAPHQL_ENDPOINT=https:\/\/yoursite.com\/graphql<\/code><\/p>\n\n\n\n<p>(add your WordPress backend&#8217;s WPGraphQL URL)<\/p>\n\n\n\n<p>This makes the WPGraphQL URL of our WordPress site available to our application through an environment variable. By default, Next.js will look for a file named <code>.env.local<\/code> in the root directory of the project to load any <a href=\"https:\/\/nextjs.org\/docs\/basic-features\/environment-variables\">environment variables<\/a>.<\/p>\n\n\n\n<p>Run <code>npm run dev<\/code> and you should be able to visit <a href=\"http:\/\/localhost:3000\">http:\/\/localhost:3000<\/a> and see this page with the first 5 posts from your WordPress backend:<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/Usw92qm6JmGGP6V3Mbbdggej1cNK905i4i7tX-JPzywOMNlySDmvWyLLio7LeIZdOXjXdZaF6bYebMgudXxmJ0PabEgHe-vxCqboML9kBw6s94LaMUCNOM2_LujTW-57hz79QY4ngzj5Fxq-a5mb2Cg\" width=\"624\" height=\"376\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Next.js 13 Paradigm Changes<\/h2>\n\n\n\n<p>Before we dive into the repository and code for this example walkthrough, let&#8217;s quickly define the new paradigm structure in Next.js 13.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">App Router<\/h3>\n\n\n\n<p>In the root of the project, Next.js 13 uses what is called the App Router.&nbsp; In previous versions of Next.js, they used what is called the Pages directory.&nbsp;&nbsp;<br><a href=\"https:\/\/nextjs.org\/docs\/app\/building-your-application\/routing#the-app-router\">The app router is represented by a top-level folder in the project named app<\/a>.<\/p>\n\n\n\n<p>Within the App folder, you nest other folders to define routes, and the files inside these folders are used to define the UI.&nbsp; By default, all the files created in the app router are React Server Components.&nbsp;<\/p>\n\n\n\n<p>The Pages Router in Next.js 12 utilized a file-based router built on the concept of pages. When a file is added to the pages directory it&#8217;s automatically available as a route.<\/p>\n\n\n\n<p>The App Router in comparison handles the overall routing and navigation for your entire application. It is responsible for rendering the correct pages based on the URL and managing the transitions between pages.&nbsp; A folder defines a route in this system.&nbsp; A route is a single path of nested folders, from a root folder down to a leaf folder which will include files that are used to create the UI.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Route Segments<\/h3>\n\n\n\n<p>Routes are commonly called route segments since they are folders.&nbsp; Dynamic routes are referred to as Dynamic segments.<\/p>\n\n\n\n<p>When you create a route, you add it to the app directory.&nbsp; When you want that route to be dynamic, you add brackets around the name of that folder which is very similar to Next.js 12.&nbsp; The difference is that Next.js 12 uses files for this, whereas Next.js 13 uses folders.<\/p>\n\n\n\n<p>For example:<\/p>\n\n\n\n<p><code>app\/post\/[uri]<\/code><\/p>\n\n\n\n<p>If you want a folder to be bypassed as a route, you wrap parentheses around it and that tells Next.js to not add it as a route in the URL.&nbsp;&nbsp;An example would be if you wanted a folder to be named dashboard but not part of the URL: <code>(dashboard)<\/code><\/p>\n\n\n\n<p>For our example, we will be using the folder named post which will be our single post route, and the parameter we will be grabbing the single post data by will be the URI.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Folders And Files<\/h3>\n\n\n\n<p>The folders in Next.js 13 represent the route and path of what you will see in the URL.<\/p>\n\n\n\n<p><br>Files on the other hand are used to create the UI and are rendered on the browser in relation to the route segment they are nested in.&nbsp; <a href=\"https:\/\/nextjs.org\/docs\/app\/building-your-application\/routing#file-conventions\">The file conventions are provided by Next.js <\/a>13 to create a UI with specific behavior in nested routes.&nbsp; In our project example, we will be using <code>page<\/code>, <code>loading<\/code>, and <code>layout<\/code> with the extension <code>.jsx<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Data Fetching<\/strong><\/h3>\n\n\n\n<p><a href=\"https:\/\/nextjs.org\/docs\/app\/building-your-application\/data-fetching\/fetching-caching-and-revalidating#fetching-data-on-the-server-with-fetch\">Next.js extends the fetch Web API<\/a> to allow you to configure the caching and revalidating behavior for each fetch request on the server. React extends fetch to automatically memoize fetch requests while rendering a React component tree.<\/p>\n\n\n\n<p>You can use fetch with async\/await in Server Components, in Route Handlers, and in Server Actions.&nbsp; In our example, we will use the fetch API to grab data from our WPGraphQL endpoint.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rendering Server and Client Components<\/h3>\n\n\n\n<p>Next.js 13, allows you the capability to create hybrid applications so that parts of the code can be rendered on the server or the client.&nbsp;&nbsp;<\/p>\n\n\n\n<p>By default, <a href=\"https:\/\/nextjs.org\/docs\/app\/building-your-application\/rendering\/server-components\">components in Next.js 13 are React Server Components<\/a> that are rendered on the server and can be optionally cached on it.&nbsp; This is now the default render method and <a href=\"https:\/\/nextjs.org\/docs\/app\/building-your-application\/rendering\/server-components#benefits-of-server-rendering\">there are many benefits to doing the rendering on the server<\/a>.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Our example will take advantage of the benefits it gives for data fetching and caching.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example Project<\/h2>\n\n\n\n<p>Now that we have a high-level understanding of the new paradigm in Next.js 13, let\u2019s dive into our repository to see it in action.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Home Page<\/h3>\n\n\n\n<p>Starting in the root of the App router folder, we have a <code>page.jsx<\/code> file.&nbsp; This file represents the home page of the site:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> Link <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\/link\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { Suspense } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> Loading <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/loading\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getPosts<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> query = <span class=\"hljs-string\">`<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  {<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    posts(first: 5) {<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      nodes {<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">        title<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">        content<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">        uri<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      }<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    }<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  }<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    `<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> res = <span class=\"hljs-keyword\">await<\/span> fetch(\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">`<span class=\"hljs-subst\">${process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT}<\/span>?query=<span class=\"hljs-subst\">${<span class=\"hljs-built_in\">encodeURIComponent<\/span>(<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">      query<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">    )}<\/span>`<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">\"GET\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">headers<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>      },\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">next<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attr\">revalidate<\/span>: <span class=\"hljs-number\">0<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>      },\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>  );\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> { data } = <span class=\"hljs-keyword\">await<\/span> res.json();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> data.posts.nodes;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">PostList<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> posts = <span class=\"hljs-keyword\">await<\/span> getPosts();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> (\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"xml\"><span class=\"hljs-tag\">&lt;&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\">      {posts.map((post) =&gt; (<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\">        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{post.uri}<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"card\"<\/span>&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Suspense<\/span> <span class=\"hljs-attr\">fallback<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Loading<\/span> \/&gt;<\/span>}&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Link<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">{<\/span>`\/<span class=\"hljs-attr\">post<\/span>\/${<span class=\"hljs-attr\">post.uri<\/span>}`}&gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span>{post.title}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">                <span class=\"hljs-attr\">dangerouslySetInnerHTML<\/span>=<span class=\"hljs-string\">{{<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">                  <span class=\"hljs-attr\">__html:<\/span> <span class=\"hljs-attr\">post.content.slice<\/span>(<span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">200<\/span>) + \"<span class=\"hljs-attr\">...<\/span>\",<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">                }}<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">              \/&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Link<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Suspense<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      ))}<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">    <span class=\"hljs-tag\">&lt;\/&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">  );<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">}<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>At the top of the file, we are going to use client-side navigation with the <code>next\/link<\/code> component, and the <code>Suspense<\/code> component from React to handle asynchronous data loading and a custom Loading state.<\/p>\n\n\n\n<p>In order to fetch our data, this component by default is a React Server Component and we define an async function named <code>getPosts<\/code>.&nbsp; This is a query that fetches the first 5 posts, with the fields we declare.<\/p>\n\n\n\n<p>Then, we await a <code>GET<\/code> request using <code>fetch<\/code> to grab data from the WPGraphQL endpoint.\u00a0 This request will be cached on the network and not the Next.js server.\u00a0 In the object, we have the content type header of the request and the <code>next.revalidate<\/code> property with the value set to 0.\u00a0 This tells Next.js to bypass the cache and have everything fetched anew upon every request.\u00a0\u00a0<\/p>\n\n\n\n<p>After that, we deserialize the response JSON and extract the <code>data<\/code> field, returning only the <code>nodes<\/code> from <code>posts<\/code>.&nbsp;<\/p>\n\n\n\n<p>Then the main functional component is <code>PostList<\/code> and the variable type calls <code>getPosts<\/code> to fetch the posts and store them in the posts variable.<\/p>\n\n\n\n<p><br>Lastly, we return the JSX and the <code>Link<\/code> needed to allow the user to click on the post title and excerpt to go to its details page and wrap the component needed.&nbsp; This gets us the data rendered on the browser which we saw earlier upon setup.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Layout &amp; Loading File<\/strong><\/h4>\n\n\n\n<p>Staying in the root of the app folder, we see the new naming file conventions. These conventions are special files that tell Next.js what behavior to execute in the UI.<\/p>\n\n\n\n<p>In the old Pages Router, you could name a file whatever you wanted it to be and still use it as an actual layout that functioned as a wrapper for your application.&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<p>We have a layout component that wraps any page component in the application and this automatically happens when you create a <code>layout.jsx<\/code> file.&nbsp; This is a Layout file and it is named Layout.&nbsp; We also have a Navbar file that is being imported from the components folder in the layout file.&nbsp;&nbsp;<\/p>\n\n\n\n<p>The other file to notice is named <code>loading.jsx<\/code> which is our custom loading component.&nbsp; This is the file convention naming as well that Next.js 13 uses.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Making the Post Page Dynamic<\/strong><\/h3>\n\n\n\n<p>In order to give users the ability to click on a post from our home page and navigate them to a single post detail page, we need to add a folder that represents the route and URL of that dynamic path first.&nbsp; In our project, we add it to the root of the app directory and call it <code>post<\/code>.&nbsp;<\/p>\n\n\n\n<p>The post folder will represent the route segment in the URL and then we need to add a dynamic route segment to this in order to grab a single post and its details via whatever parameter we specify.&nbsp; In this project, we will grab it by its URI.<\/p>\n\n\n\n<p>In the Post folder, we create another nested folder called <code>uri<\/code> and wrap brackets on it.&nbsp; This tells Next.js to make this dynamic which allows this segment to be passed as the params prop to the page.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.16.08-AM.png\" alt=\"\" class=\"wp-image-5590\"\/><\/figure>\n\n\n\n<p>Now that we have our route segments set up and the parameter dynamically set, we need to create the UI with a file for this route.&nbsp; We do that by adding a <code>page.jsx<\/code> file in the nested <code>[uri]<\/code> folder within the Post folder.&nbsp; Let\u2019s break down what is going on here.&nbsp;&nbsp;<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { Suspense } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> Loading <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/..\/loading\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getPost<\/span>(<span class=\"hljs-params\">uri<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> query = <span class=\"hljs-string\">`<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  query GetPostByUri($uri: ID!) {<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    post(id: $uri, idType: URI) {<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      title<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      content<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      <\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    }<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  }<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      `<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> variables = {\n<\/span><\/span><span class='shcb-loc'><span>    uri,\n<\/span><\/span><span class='shcb-loc'><span>  };\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> res = <span class=\"hljs-keyword\">await<\/span> fetch(process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT, {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">\"POST\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">headers<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    },\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">next<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">revalidate<\/span>: <span class=\"hljs-number\">60<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    },\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">body<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify({ query, variables }),\n<\/span><\/span><span class='shcb-loc'><span>  });\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> responseBody = <span class=\"hljs-keyword\">await<\/span> res.json();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">if<\/span> (responseBody &amp;&amp; responseBody.data &amp;&amp; responseBody.data.post) {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">return<\/span> responseBody.data.post;\n<\/span><\/span><span class='shcb-loc'><span>  } <span class=\"hljs-keyword\">else<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Error<\/span>(<span class=\"hljs-string\">\"Failed to fetch the post\"<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">PostDetails<\/span>(<span class=\"hljs-params\">{ params }<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> post = <span class=\"hljs-keyword\">await<\/span> getPost(params.uri);\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> (\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav<\/span>&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>{post.title}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">nav<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Suspense<\/span> <span class=\"hljs-attr\">fallback<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Loading<\/span> \/&gt;<\/span>}&gt;<\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"card\"<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{post.uri}<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">dangerouslySetInnerHTML<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">__html:<\/span> <span class=\"hljs-attr\">post.content<\/span> }} \/&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Suspense<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">  );<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">}<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>It is very similar to the code on our home page except, the WPGraphQL query is grabbing a single post via its URI.<\/p>\n\n\n\n<p>The 2 major differences are the WPGraphQL query which is an async function that takes an id parameter and the query string fetches a single post by its <code>uri<\/code>.<\/p>\n\n\n\n<p>Then we set up a variables object containing the uri.<\/p>\n\n\n\n<p>In the execution of the fetch request, we use the POST method, and the <code>next.revalidate<\/code> method is set to 60 which tells Next.js to use time-based revalidation every 60 seconds.\u00a0 I wanted to show an example of the optionality you can have in <a href=\"https:\/\/nextjs.org\/docs\/app\/building-your-application\/caching\">Next.js 13 at the function level on caching, time based revalidation, and method requests<\/a>.\u00a0\u00a0<\/p>\n\n\n\n<p>Lastly, the main functional component renders the JSX onto the browser when we visit a post link detail:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"615\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.20.30-AM-1024x615.png\" alt=\"\" class=\"wp-image-5592\" srcset=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.20.30-AM-1024x615.png 1024w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.20.30-AM-300x180.png 300w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.20.30-AM-768x461.png 768w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.20.30-AM-1536x923.png 1536w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.20.30-AM-2048x1230.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion&nbsp;<\/h2>\n\n\n\n<p>Next.js 13 is a new version of the most used meta framework on top of React. It introduces new ways to handle data, create routes and files as well as rendering methods.&nbsp; Mix it with headless WordPress and WPGraphQL and you have a super stoked combination!&nbsp; We hope you have a better understanding of how it all works together.<\/p>\n\n\n\n<p>Stay tuned for more Next.js 13 and headless WordPress content coming soon!!<\/p>\n\n\n\n<p>As always, stoked to hear your feedback and any questions you might have on headless WordPress! Hit us up in our <a href=\"https:\/\/discord.com\/invite\/J2khkF9XYK\">Discord!<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, you will learn how to create a simple headless WordPress app using Next.js 13 and WPGraphQL. This tutorial assumes a basic understanding of React , Next.js 12, [&hellip;]<\/p>\n","protected":false},"author":20,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_EventAllDay":false,"_EventTimezone":"","_EventStartDate":"","_EventEndDate":"","_EventStartDateUTC":"","_EventEndDateUTC":"","_EventShowMap":false,"_EventShowMapLink":false,"_EventURL":"","_EventCost":"","_EventCostDescription":"","_EventCurrencySymbol":"","_EventCurrencyCode":"","_EventCurrencyPosition":"","_EventDateTimeSeparator":"","_EventTimeRangeSeparator":"","_EventOrganizerID":[],"_EventVenueID":[],"_OrganizerEmail":"","_OrganizerPhone":"","_OrganizerWebsite":"","_VenueAddress":"","_VenueCity":"","_VenueCountry":"","_VenueProvince":"","_VenueState":"","_VenueZip":"","_VenuePhone":"","_VenueURL":"","_VenueStateProvince":"","_VenueLat":"","_VenueLng":"","_VenueShowMap":false,"_VenueShowMapLink":false,"footnotes":""},"categories":[23],"tags":[],"class_list":["post-5589","post","type-post","status-publish","format-standard","hentry","category-headless"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Next.js 13 and WPGraphQL in headless WordPress - Builders<\/title>\n<meta name=\"description\" content=\"In this article, you will learn how to create a simple headless WordPress app using Next.js 13 and WPGraphQL. This tutorial assumes a basic understanding of React , Next.js 12, and WordPress. Using the prepared GitHub repository will allow us to focus on points specific to Next.js 13 and some of its new features.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Next.js 13 and WPGraphQL in headless WordPress - Builders\" \/>\n<meta property=\"og:description\" content=\"In this article, you will learn how to create a simple headless WordPress app using Next.js 13 and WPGraphQL. This tutorial assumes a basic understanding of React , Next.js 12, and WordPress. Using the prepared GitHub repository will allow us to focus on points specific to Next.js 13 and some of its new features.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/\" \/>\n<meta property=\"og:site_name\" content=\"Builders\" \/>\n<meta property=\"article:published_time\" content=\"2023-10-19T14:26:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-11-13T17:40:01+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.24.01-AM.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2222\" \/>\n\t<meta property=\"og:image:height\" content=\"854\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Francis Agulto\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@wpebuilders\" \/>\n<meta name=\"twitter:site\" content=\"@wpebuilders\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Francis Agulto\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/\"},\"author\":{\"name\":\"Francis Agulto\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/person\\\/bcdcb4ac0b215c34b6b30e440a24dc54\"},\"headline\":\"Next.js 13 and WPGraphQL in headless WordPress\",\"datePublished\":\"2023-10-19T14:26:44+00:00\",\"dateModified\":\"2023-11-13T17:40:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/\"},\"wordCount\":1992,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/lh6.googleusercontent.com\\\/PqxqlVI7vwv-2dkMtiNeJlcWhDoiQjJFFzYMkRkbzIGlF5uYiPUAH2S46kUkQf4VIgerM-mjJ7lQzLVauRljc86phK6GMDHdAh9Uc8cNRhdqNrvzdEgR-cu7hxg_nEzNcJt5MzE0Z359ziVfa3MTNjI\",\"articleSection\":[\"Headless\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/\",\"name\":\"Next.js 13 and WPGraphQL in headless WordPress - Builders\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/lh6.googleusercontent.com\\\/PqxqlVI7vwv-2dkMtiNeJlcWhDoiQjJFFzYMkRkbzIGlF5uYiPUAH2S46kUkQf4VIgerM-mjJ7lQzLVauRljc86phK6GMDHdAh9Uc8cNRhdqNrvzdEgR-cu7hxg_nEzNcJt5MzE0Z359ziVfa3MTNjI\",\"datePublished\":\"2023-10-19T14:26:44+00:00\",\"dateModified\":\"2023-11-13T17:40:01+00:00\",\"description\":\"In this article, you will learn how to create a simple headless WordPress app using Next.js 13 and WPGraphQL. This tutorial assumes a basic understanding of React , Next.js 12, and WordPress. Using the prepared GitHub repository will allow us to focus on points specific to Next.js 13 and some of its new features.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/#primaryimage\",\"url\":\"https:\\\/\\\/lh6.googleusercontent.com\\\/PqxqlVI7vwv-2dkMtiNeJlcWhDoiQjJFFzYMkRkbzIGlF5uYiPUAH2S46kUkQf4VIgerM-mjJ7lQzLVauRljc86phK6GMDHdAh9Uc8cNRhdqNrvzdEgR-cu7hxg_nEzNcJt5MzE0Z359ziVfa3MTNjI\",\"contentUrl\":\"https:\\\/\\\/lh6.googleusercontent.com\\\/PqxqlVI7vwv-2dkMtiNeJlcWhDoiQjJFFzYMkRkbzIGlF5uYiPUAH2S46kUkQf4VIgerM-mjJ7lQzLVauRljc86phK6GMDHdAh9Uc8cNRhdqNrvzdEgR-cu7hxg_nEzNcJt5MzE0Z359ziVfa3MTNjI\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/next-js-13-and-wpgraphql-in-headless-wordpress\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Next.js 13 and WPGraphQL in headless WordPress\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#website\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\",\"name\":\"Builders\",\"description\":\"Reimagining the way we build with WordPress.\",\"publisher\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\",\"name\":\"WP Engine\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/WP-Engine-Horizontal@2x.png\",\"contentUrl\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/WP-Engine-Horizontal@2x.png\",\"width\":348,\"height\":68,\"caption\":\"WP Engine\"},\"image\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/wpebuilders\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCh1WuL54XFb9ZI6m6goFv1g\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/person\\\/bcdcb4ac0b215c34b6b30e440a24dc54\",\"name\":\"Francis Agulto\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g\",\"caption\":\"Francis Agulto\"},\"description\":\"Fran Agulto is a Developer Advocate at WP Engine. He is a lover of all things headless WordPress, Rock Climbing, and overall being stoked for people that love what they do and share that stoke with others! Follow me on Twitter for cool stoked headless WP!\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/author\\\/francis-agultowpengine-com-2-2-2-2-2-2-2-2-2-2-2-2\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Next.js 13 and WPGraphQL in headless WordPress - Builders","description":"In this article, you will learn how to create a simple headless WordPress app using Next.js 13 and WPGraphQL. This tutorial assumes a basic understanding of React , Next.js 12, and WordPress. Using the prepared GitHub repository will allow us to focus on points specific to Next.js 13 and some of its new features.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/","og_locale":"en_US","og_type":"article","og_title":"Next.js 13 and WPGraphQL in headless WordPress - Builders","og_description":"In this article, you will learn how to create a simple headless WordPress app using Next.js 13 and WPGraphQL. This tutorial assumes a basic understanding of React , Next.js 12, and WordPress. Using the prepared GitHub repository will allow us to focus on points specific to Next.js 13 and some of its new features.","og_url":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/","og_site_name":"Builders","article_published_time":"2023-10-19T14:26:44+00:00","article_modified_time":"2023-11-13T17:40:01+00:00","og_image":[{"width":2222,"height":854,"url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.24.01-AM.png","type":"image\/png"}],"author":"Francis Agulto","twitter_card":"summary_large_image","twitter_creator":"@wpebuilders","twitter_site":"@wpebuilders","twitter_misc":{"Written by":"Francis Agulto","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/#article","isPartOf":{"@id":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/"},"author":{"name":"Francis Agulto","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/bcdcb4ac0b215c34b6b30e440a24dc54"},"headline":"Next.js 13 and WPGraphQL in headless WordPress","datePublished":"2023-10-19T14:26:44+00:00","dateModified":"2023-11-13T17:40:01+00:00","mainEntityOfPage":{"@id":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/"},"wordCount":1992,"commentCount":0,"publisher":{"@id":"https:\/\/wpengine.com\/builders\/#organization"},"image":{"@id":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/#primaryimage"},"thumbnailUrl":"https:\/\/lh6.googleusercontent.com\/PqxqlVI7vwv-2dkMtiNeJlcWhDoiQjJFFzYMkRkbzIGlF5uYiPUAH2S46kUkQf4VIgerM-mjJ7lQzLVauRljc86phK6GMDHdAh9Uc8cNRhdqNrvzdEgR-cu7hxg_nEzNcJt5MzE0Z359ziVfa3MTNjI","articleSection":["Headless"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/","url":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/","name":"Next.js 13 and WPGraphQL in headless WordPress - Builders","isPartOf":{"@id":"https:\/\/wpengine.com\/builders\/#website"},"primaryImageOfPage":{"@id":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/#primaryimage"},"image":{"@id":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/#primaryimage"},"thumbnailUrl":"https:\/\/lh6.googleusercontent.com\/PqxqlVI7vwv-2dkMtiNeJlcWhDoiQjJFFzYMkRkbzIGlF5uYiPUAH2S46kUkQf4VIgerM-mjJ7lQzLVauRljc86phK6GMDHdAh9Uc8cNRhdqNrvzdEgR-cu7hxg_nEzNcJt5MzE0Z359ziVfa3MTNjI","datePublished":"2023-10-19T14:26:44+00:00","dateModified":"2023-11-13T17:40:01+00:00","description":"In this article, you will learn how to create a simple headless WordPress app using Next.js 13 and WPGraphQL. This tutorial assumes a basic understanding of React , Next.js 12, and WordPress. Using the prepared GitHub repository will allow us to focus on points specific to Next.js 13 and some of its new features.","breadcrumb":{"@id":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/#primaryimage","url":"https:\/\/lh6.googleusercontent.com\/PqxqlVI7vwv-2dkMtiNeJlcWhDoiQjJFFzYMkRkbzIGlF5uYiPUAH2S46kUkQf4VIgerM-mjJ7lQzLVauRljc86phK6GMDHdAh9Uc8cNRhdqNrvzdEgR-cu7hxg_nEzNcJt5MzE0Z359ziVfa3MTNjI","contentUrl":"https:\/\/lh6.googleusercontent.com\/PqxqlVI7vwv-2dkMtiNeJlcWhDoiQjJFFzYMkRkbzIGlF5uYiPUAH2S46kUkQf4VIgerM-mjJ7lQzLVauRljc86phK6GMDHdAh9Uc8cNRhdqNrvzdEgR-cu7hxg_nEzNcJt5MzE0Z359ziVfa3MTNjI"},{"@type":"BreadcrumbList","@id":"https:\/\/wpengine.com\/builders\/next-js-13-and-wpgraphql-in-headless-wordpress\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wpengine.com\/builders\/"},{"@type":"ListItem","position":2,"name":"Next.js 13 and WPGraphQL in headless WordPress"}]},{"@type":"WebSite","@id":"https:\/\/wpengine.com\/builders\/#website","url":"https:\/\/wpengine.com\/builders\/","name":"Builders","description":"Reimagining the way we build with WordPress.","publisher":{"@id":"https:\/\/wpengine.com\/builders\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wpengine.com\/builders\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/wpengine.com\/builders\/#organization","name":"WP Engine","url":"https:\/\/wpengine.com\/builders\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/","url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png","contentUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png","width":348,"height":68,"caption":"WP Engine"},"image":{"@id":"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/wpebuilders","https:\/\/www.youtube.com\/channel\/UCh1WuL54XFb9ZI6m6goFv1g"]},{"@type":"Person","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/bcdcb4ac0b215c34b6b30e440a24dc54","name":"Francis Agulto","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g","caption":"Francis Agulto"},"description":"Fran Agulto is a Developer Advocate at WP Engine. He is a lover of all things headless WordPress, Rock Climbing, and overall being stoked for people that love what they do and share that stoke with others! Follow me on Twitter for cool stoked headless WP!","url":"https:\/\/wpengine.com\/builders\/author\/francis-agultowpengine-com-2-2-2-2-2-2-2-2-2-2-2-2\/"}]}},"_links":{"self":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts\/5589","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/comments?post=5589"}],"version-history":[{"count":0,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts\/5589\/revisions"}],"wp:attachment":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/media?parent=5589"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/categories?post=5589"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/tags?post=5589"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}