{"id":36234,"date":"2024-10-29T07:00:00","date_gmt":"2024-10-29T14:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=36234"},"modified":"2025-04-16T12:38:06","modified_gmt":"2025-04-16T19:38:06","slug":"cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2","title":{"rendered":"Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)"},"content":{"rendered":"\n<p>In <a href=\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-1\">Part 1<\/a>, we\u2019ll set up WordPress as a headless CMS with WPGraphQL, grab our public ID data from our specific Cloudinary assets, and create the custom field in WordPress that is necessary to link the Cloudinary asset ID\u2019s to WordPress and Astro.&nbsp;<\/p>\n\n\n\n<p>In Part 2, we\u2019ll put everything together by creating an Astro app and rendering it on the browser.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Create an Astro Project<\/h2>\n\n\n\n<p>The first thing we need to do is create a new Astro project.&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to your terminal and run these commands:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">npm<\/span> <span class=\"hljs-selector-tag\">create<\/span> <span class=\"hljs-selector-tag\">astro<\/span><span class=\"hljs-keyword\">@latest<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0npm install astro-cloudinary\n\nnpm\u00a0 install graphql<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>&nbsp;Once you do that, create a .env.local file in the root of your project and add these keys and values, and paste the values in from your Cloudinary account accordingly.<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">PUBLIC_CLOUDINARY_CLOUD_NAME=\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0PUBLIC_CLOUDINARY_API_KEY=\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLOUDINARY_API_SECRET=\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0WORDPRESS_API_URL=<\/code><\/span><\/pre>\n\n\n<p>Once you paste those keys into your <code>.env.local<\/code> file, you can add the respective values they need.&nbsp;Your Cloudinary values can all be found in your Cloudinary account dashboard and your WP API URL is your WordPress site\u2019s URL.&nbsp;&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Connect Astro and WordPress via WPGraphQL<\/h2>\n\n\n\n<p>Now that we have the environment variables setup in our Astro project, the next step is to create some GraphQL requests to fetch data from WordPress. In the <code>src<\/code> folder, create another folder called <code>lib<\/code>. In this <code>lib<\/code> folder, create a file called <code>api.js<\/code>. In that file, copy and paste this code block:&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-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> WORDPRESS_API_URL = <span class=\"hljs-keyword\">import<\/span>.meta.env.WORDPRESS_API_URL;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">navQuery<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> siteNavQueryRes = <span class=\"hljs-keyword\">await<\/span> fetch(WORDPRESS_API_URL, {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">\"POST\"<\/span>,\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">headers<\/span>: { <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span> },\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">body<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify({\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">query<\/span>: <span class=\"hljs-string\">`\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0menus(where: {location: PRIMARY}) {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0nodes {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0menuItems {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0nodes {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uri\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0url\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0order\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0label\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0generalSettings {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0title\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0url\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0description\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0`<\/span>,\n\n\u00a0\u00a0\u00a0\u00a0}),\n\n\u00a0\u00a0});\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> { data } = <span class=\"hljs-keyword\">await<\/span> siteNavQueryRes.json();\n\n\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> data;\n\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">homePagePostsQuery<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(WORDPRESS_API_URL, {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">\"POST\"<\/span>,\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">headers<\/span>: { <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span> },\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">body<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify({\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">query<\/span>: <span class=\"hljs-string\">`\n\n\u00a0\u00a0\u00a0\u00a0query GetPosts {\n\n\u00a0\u00a0posts {\n\n\u00a0\u00a0\u00a0\u00a0nodes {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0title\n\nuri\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cloudinaryAsset{\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cloudinaryPublicId\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0}\n\n}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0`<\/span>,\n\n\u00a0\u00a0\u00a0\u00a0}),\n\n\u00a0\u00a0});\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> { data } = <span class=\"hljs-keyword\">await<\/span> response.json();\n\n\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> data;\n\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getNodeByURI<\/span>(<span class=\"hljs-params\">uri<\/span>) <\/span>{\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(WORDPRESS_API_URL, {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">\"POST\"<\/span>,\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">headers<\/span>: { <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span> },\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">body<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify({\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">query<\/span>: <span class=\"hljs-string\">`\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0query GetNodeByURI($uri: String!) {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0nodeByUri(uri: $uri) {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0__typename\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isContentNode\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isTermNode\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0... on Post {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0title\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0date\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uri\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0excerpt\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0content\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0categories {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0nodes {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uri\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0featuredImage {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0srcSet\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sourceUrl\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0altText\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mediaDetails {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0height\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0width\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0... on Page {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0title\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uri\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0date\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0content\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0... on Category {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0posts {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0nodes {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0date\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0title\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0excerpt\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uri\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0categories {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0nodes {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uri\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0featuredImage {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0srcSet\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sourceUrl\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0altText\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mediaDetails {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0height\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0width\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0`<\/span>,\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">variables<\/span>: {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">uri<\/span>: uri,\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\n\n\u00a0\u00a0\u00a0\u00a0}),\n\n\u00a0\u00a0});\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> { data } = <span class=\"hljs-keyword\">await<\/span> response.json();\n\n\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> data;\n\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getAllUris<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(<span class=\"hljs-keyword\">import<\/span>.meta.env.WORDPRESS_API_URL, {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">\"POST\"<\/span>,\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">headers<\/span>: { <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span> },\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">body<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify({\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">query<\/span>: <span class=\"hljs-string\">`\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0query GetAllUris {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0posts(first: 100) {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0nodes {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uri\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pages(first: 100) {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0nodes {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uri\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0`<\/span>,\n\n\u00a0\u00a0\u00a0\u00a0}),\n\n\u00a0\u00a0});\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> { data } = <span class=\"hljs-keyword\">await<\/span> response.json();\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Combine all URIs from posts and pages<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> uris = &#91;...data.posts.nodes, ...data.pages.nodes]\n\n\u00a0\u00a0\u00a0\u00a0.filter(<span class=\"hljs-function\">(<span class=\"hljs-params\">node<\/span>) =&gt;<\/span> node.uri !== <span class=\"hljs-literal\">null<\/span>)\n\n\u00a0\u00a0\u00a0\u00a0.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">node<\/span>) =&gt;<\/span> ({\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">params<\/span>: {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">uri<\/span>: node.uri.substring(<span class=\"hljs-number\">1<\/span>), <span class=\"hljs-comment\">\/\/ Remove leading '\/' if necessary<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\n\n\u00a0\u00a0\u00a0\u00a0}));\n\n\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> uris;\n\n}<\/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>This entire code block is all our GraphQL queries needed for this site. Its function is to fetch the post title, URI, and the custom <code>cloudinaryPublicId<\/code> field from WordPress. It will also allow us to add a dynamic route file for a single post detail page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Create a Home Page to Render Cloudinary Assets<\/h2>\n\n\n\n<p>We&#8217;re now ready to create a home page that renders Cloudinary assets and matches posts from WordPress to a Cloudinary public ID. In <code>src\/pages\/index.js<\/code>, copy and paste this code block in:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">---\n\n<span class=\"hljs-keyword\">import<\/span> { getCollection } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'astro:content'<\/span>;\n\n<span class=\"hljs-keyword\">import<\/span> { CldImage } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'astro-cloudinary'<\/span>;\n\n<span class=\"hljs-keyword\">import<\/span> { homePagePostsQuery } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/lib\/api\"<\/span>;\u00a0 <span class=\"hljs-comment\">\/\/ Your WPGraphQL query function<\/span>\n\n<span class=\"hljs-comment\">\/\/ Fetch the Cloudinary assets<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> assets = <span class=\"hljs-keyword\">await<\/span> getCollection(<span class=\"hljs-string\">'assets'<\/span>);\n\n<span class=\"hljs-comment\">\/\/ Fetch the posts data from WordPress using the homePagePostsQuery function<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">await<\/span> homePagePostsQuery();\n\n<span class=\"hljs-keyword\">const<\/span> posts = data.posts.nodes;\n\n<span class=\"hljs-comment\">\/\/ Debugging: Log assets and posts to check the structure<\/span>\n\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"Cloudinary Assets:\"<\/span>, assets);\n\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"WordPress Posts:\"<\/span>, posts);\n\n<span class=\"hljs-comment\">\/\/ Match posts to assets based on cloudinaryPublicId<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> galleryItems = posts.map(<span class=\"hljs-function\"><span class=\"hljs-params\">post<\/span> =&gt;<\/span> {\n\n\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span> (!post.cloudinaryAsset || !post.cloudinaryAsset.cloudinaryPublicId) {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> { post, <span class=\"hljs-attr\">asset<\/span>: <span class=\"hljs-literal\">null<\/span> };\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Use the cloudinaryPublicId directly from WordPress (no need to prepend folder)<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> fullCloudinaryPublicId = post.cloudinaryAsset.cloudinaryPublicId;\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Log the constructed full public ID for debugging<\/span>\n\n\u00a0\u00a0<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"Post Full Cloudinary Public ID:\"<\/span>, fullCloudinaryPublicId);\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Try to find the matching asset<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> matchedAsset = assets.find(<span class=\"hljs-function\"><span class=\"hljs-params\">asset<\/span> =&gt;<\/span> asset.data.public_id === fullCloudinaryPublicId);\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Log if a match was found or not<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span> (matchedAsset) {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Match found for post: <span class=\"hljs-subst\">${post.title}<\/span>`<\/span>);\n\n\u00a0\u00a0} <span class=\"hljs-keyword\">else<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`No match found for post: <span class=\"hljs-subst\">${post.title}<\/span>`<\/span>);\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0post,\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">asset<\/span>: matchedAsset || <span class=\"hljs-literal\">null<\/span>\u00a0 <span class=\"hljs-comment\">\/\/ Fallback in case no asset is found<\/span>\n\n\u00a0\u00a0};\n\n});\n\n---\n\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n\n\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"h1\"<\/span>&gt;<\/span>Headless WP Astro Asset Loader Gallery<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\n\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"gallery\"<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0{galleryItems.map(({ post, asset }) =&gt; (\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"gallery-item\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">{post.uri}<\/span> &gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{asset ? (\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">{post.uri}<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{asset.data.public_id}<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{300}<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">{200}<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">\"fill\"<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">gravity<\/span>=<span class=\"hljs-string\">\"auto\"<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{post.title}<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0) : (\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>No corresponding asset found<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">{post.uri}<\/span>&gt;<\/span>{post.title}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0))}\n\n\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/span>\n\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">style<\/span>&gt;<\/span><span class=\"css\">\n\n\u00a0\u00a0<span class=\"hljs-selector-class\">.h1<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">text-align<\/span>: center;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">font-family<\/span>: monospace;\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/* Flexbox layout for gallery *\/<\/span>\n\n\u00a0\u00a0<span class=\"hljs-selector-class\">.gallery<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">display<\/span>: flex;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">flex-wrap<\/span>: wrap;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">justify-content<\/span>: space-between;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">20px<\/span>;\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/* Style for each gallery item *\/<\/span>\n\n\u00a0\u00a0<span class=\"hljs-selector-class\">.gallery-item<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">10px<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">text-align<\/span>: center;\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/* Set width to ensure consistent sizing *\/<\/span>\n\n\u00a0\u00a0<span class=\"hljs-selector-class\">.gallery-item<\/span> <span class=\"hljs-selector-tag\">img<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">max-width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">height<\/span>: auto;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">8px<\/span>;\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/* Ensure h3 and description are styled properly *\/<\/span>\n\n\u00a0\u00a0<span class=\"hljs-selector-class\">.gallery-item<\/span> <span class=\"hljs-selector-tag\">h3<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">margin-top<\/span>: <span class=\"hljs-number\">10px<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-number\">16px<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">font-weight<\/span>: bold;\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/* Add styling for the \"Read More\" links *\/<\/span>\n\n\u00a0\u00a0<span class=\"hljs-selector-tag\">a<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">display<\/span>: inline-block;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">margin-top<\/span>: <span class=\"hljs-number\">10px<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-number\">#003559<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">text-decoration<\/span>: none;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">font-weight<\/span>: bold;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">font-size<\/span>: large;\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-selector-tag\">a<\/span><span class=\"hljs-selector-pseudo\">:hover<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attribute\">text-decoration<\/span>: underline;\n\n\u00a0\u00a0}\n\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">style<\/span>&gt;<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><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>Let\u2019s break this down since there is a bit of code in this block.&nbsp; At the top of the file, we import the necessary things we need:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>import { getCollection } from 'astro:content';<\/code>.<\/strong> This imports the <code>getCollection<\/code> function from Astro&#8217;s content API, which is used to fetch assets or content collections (like images) stored in Cloudinary.<\/li>\n\n\n\n<li><strong><code>import { CldImage } from 'astro-cloudinary';<\/code>.<\/strong> This imports the CldImage component from the <code>astro-cloudinary<\/code> package. The CldImage component is responsible for rendering images directly from Cloudinary, with built-in features like responsive image handling and on-the-fly image transformations (e.g., cropping, resizing, etc.).<\/li>\n\n\n\n<li><strong><code>import { homePagePostsQuery } from \"..\/lib\/api\";<\/code>.<\/strong> This imports a custom function from the <code>api.js<\/code> file that queries the WordPress GraphQL API for a list of posts. This data is used to populate the gallery with posts and their related <a href=\"https:\/\/cloudinary.com\/products\/digital_asset_management\">Cloudinary assets<\/a>.<\/li>\n<\/ul>\n\n\n\n<p>Next we&#8217;ll fetch our data:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ Fetch the Cloudinary assets<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> assets = <span class=\"hljs-keyword\">await<\/span> getCollection(<span class=\"hljs-string\">'assets'<\/span>);\n\n<span class=\"hljs-comment\">\/\/ Fetch the posts data from WordPress using the homePagePostsQuery function<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">await<\/span> homePagePostsQuery();\n\n<span class=\"hljs-keyword\">const<\/span> posts = data.posts.nodes;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><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<ul class=\"wp-block-list\">\n<li><strong><code>const assets = await getCollection('assets');<\/code>.<\/strong> This asynchronously fetches a collection of assets from Cloudinary that were pre-configured in Astro&#8217;s content collection system. The <code>'assets'<\/code> collection contains the images that will be rendered on the homepage.<\/li>\n\n\n\n<li><strong><code>const data = await homePagePostsQuery();<\/code>. <\/strong>This asynchronously fetches the list of posts from the WordPress GraphQL API using the custom <code>homePagePostsQuery<\/code> function.<\/li>\n\n\n\n<li><strong><code>const posts = data.posts.nodes;<\/code>.<\/strong> This extracts the array of posts from the GraphQL response, which is stored in data.posts.nodes. Each post contains details such as the title, URI, and the associated Cloudinary public ID stored in WordPress.<\/li>\n<\/ul>\n\n\n\n<p>Following that, we&#8217;ll make sure to throw some debugging logs in to check data structure is accurate:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ Debugging: Log assets and posts to check the structure<\/span>\n\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"Cloudinary Assets:\"<\/span>, assets);\n\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"WordPress Posts:\"<\/span>, posts);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><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>Then we&#8217;ll match Cloudinary assets to WordPress posts like so:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\/ Match posts to assets based on cloudinaryPublicId\n\n<span class=\"hljs-keyword\">const<\/span> galleryItems = posts.map(<span class=\"hljs-function\"><span class=\"hljs-params\">post<\/span> =&gt;<\/span> {\n\n\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span> (!post.cloudinaryAsset || !post.cloudinaryAsset.cloudinaryPublicId) {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> { post, <span class=\"hljs-attr\">asset<\/span>: <span class=\"hljs-literal\">null<\/span> };\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Use the cloudinaryPublicId directly from WordPress (no need to prepend folder)<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> fullCloudinaryPublicId = post.cloudinaryAsset.cloudinaryPublicId;\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Log the constructed full public ID for debugging<\/span>\n\n\u00a0\u00a0<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"Post Full Cloudinary Public ID:\"<\/span>, fullCloudinaryPublicId);\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Try to find the matching asset<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> matchedAsset = assets.find(<span class=\"hljs-function\"><span class=\"hljs-params\">asset<\/span> =&gt;<\/span> asset.data.public_id === fullCloudinaryPublicId);\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Log if a match was found or not<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span> (matchedAsset) {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Match found for post: <span class=\"hljs-subst\">${post.title}<\/span>`<\/span>);\n\n\u00a0\u00a0} <span class=\"hljs-keyword\">else<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`No match found for post: <span class=\"hljs-subst\">${post.title}<\/span>`<\/span>);\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0post,\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">asset<\/span>: matchedAsset || <span class=\"hljs-literal\">null<\/span>\u00a0 <span class=\"hljs-comment\">\/\/ Fallback in case no asset is found<\/span>\n\n\u00a0\u00a0};\n\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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>Let&#8217;s break down what&#8217;s happening:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>const galleryItems = posts.map(post =&gt; { ... })<\/code>.<\/strong> This block of code iterates over the array of posts and attempts to match each post with its corresponding Cloudinary asset using the public ID stored in WordPress.<\/li>\n\n\n\n<li><strong><code>if (!post.cloudinaryAsset || !post.cloudinaryAsset.cloudinaryPublicId) { ... }<\/code>.<\/strong> This conditional checks if the post has a cloudinaryAsset and whether the cloudinaryPublicId is present. If either is missing, it returns the post without a corresponding asset (asset: null).<\/li>\n\n\n\n<li><strong><code>const fullCloudinaryPublicId = post.cloudinaryAsset.cloudinaryPublicId;<\/code>.<\/strong> This assigns the cloudinaryPublicId from WordPress directly to fullCloudinaryPublicId to be used for matching Cloudinary assets.<\/li>\n\n\n\n<li><strong>const matchedAsset = assets.find(asset =&gt; asset.data.public_id === fullCloudinaryPublicId);<\/strong>. This line attempts to find a match between the cloudinaryPublicId from WordPress and the public_id from Cloudinary&#8217;s assets. If a match is found, that asset is stored in matchedAsset.<\/li>\n\n\n\n<li><strong>return { post, asset: matchedAsset || null }<\/strong>. The function returns an object containing the post and the matched asset. If no match is found, the asset will be null.<\/li>\n<\/ul>\n\n\n\n<p>Once we have that set, we now can have the main content section of our code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n\n\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"h1\"<\/span>&gt;<\/span>Headless WP Astro Asset Loader Gallery<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\n\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"gallery\"<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0{galleryItems.map(({ post, asset }) =&gt; (\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"gallery-item\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">{post.uri}<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{asset ? (\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">{post.uri}<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{asset.data.public_id}<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{300}<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">{200}<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">\"fill\"<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">gravity<\/span>=<span class=\"hljs-string\">\"auto\"<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{post.title}<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0) : (\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>No corresponding asset found<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">{post.uri}<\/span>&gt;<\/span>{post.title}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0))}\n\n\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>&lt;main&gt;<\/code>.<\/strong> This is the main section of the HTML where the content will be rendered.<\/li>\n\n\n\n<li><strong><code>&lt;h1&gt;<\/code>.<\/strong> This renders the title of the page, &#8220;Headless WP Astro Asset Loader Gallery&#8221;.<\/li>\n\n\n\n<li><strong><code>{galleryItems.map(({ post, asset }) =&gt; (...)}<\/code>.<\/strong> The galleryItems array is mapped over, where each iteration renders a post and its corresponding Cloudinary asset (if available). Each post and asset combination will be rendered inside a div with the class gallery-item.<\/li>\n\n\n\n<li><strong><code>&lt;CldImage src={asset.data.public_id} ... \/&gt;<\/code>.<\/strong> If a corresponding asset is found for the post, it will be rendered using the CldImage component, which handles optimized media delivery from Cloudinary.<\/li>\n\n\n\n<li><strong><code>&lt;h3&gt;&lt;a href={post.uri}&gt;{post.title}&lt;\/a&gt;&lt;\/h3&gt;<\/code>.<\/strong> Each post&#8217;s title is displayed as a link, which points to the individual post detail page.<\/li>\n<\/ul>\n\n\n\n<p>And finally we&#8217;ll style the component at the bottom.<\/p>\n\n\n\n<p>When you run <code>npm run dev<\/code> in your terminal, you should see a page that renders assets from Cloudinary with the corresponding titles those assets are related to from WordPress:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img width=\"1024\" height=\"600\" data-public-id=\"Web_Assets\/blog\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_600,c_scale\/f_auto,q_auto\/v1730227194\/Web_Assets\/blog\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1.png?_i=AA\" alt=\"\" class=\"wp-post-36234 wp-image-36237\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1730227194\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1730227194\/Web_Assets\/blog\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1.png?_i=AA 1999w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1730227194\/Web_Assets\/blog\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1730227194\/Web_Assets\/blog\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1730227194\/Web_Assets\/blog\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1730227194\/Web_Assets\/blog\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1\/blog-Cloudinary-Asset-Loader-for-Astro-and-Headless-WordPress-Using-WPGraphQL-Part-2-1.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">Create a Dynamic Route File to Show Asset and Detail<\/h3>\n\n\n\n<p>The last thing we need to do is use Astro\u2019s support for dynamic routing to create dynamic pages that display detailed information from each post.<\/p>\n\n\n\n<p>Go to <code>src\/pages\/[uri].js<\/code> and copy and paste this code block in:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">---\n\n<span class=\"hljs-keyword\">import<\/span> { CldImage } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"astro-cloudinary\"<\/span>;\n\n<span class=\"hljs-keyword\">import<\/span> { getNodeByURI, getAllUris } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/lib\/api\"<\/span>;\n\n<span class=\"hljs-comment\">\/\/ This function tells Astro which paths to generate at build time<\/span>\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getStaticPaths<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Fetch all URIs from WordPress<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> uris = <span class=\"hljs-keyword\">await<\/span> getAllUris();\n\n\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> uris.map(<span class=\"hljs-function\"><span class=\"hljs-params\">uri<\/span> =&gt;<\/span> ({\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">params<\/span>: { <span class=\"hljs-attr\">uri<\/span>: uri.params.uri }\n\n\u00a0\u00a0}));\n\n}\n\n<span class=\"hljs-comment\">\/\/ Get the post's URI from the route parameter<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> { uri } = Astro.params;\n\n<span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">await<\/span> getNodeByURI(<span class=\"hljs-string\">`\/<span class=\"hljs-subst\">${uri}<\/span>`<\/span>);\n\n<span class=\"hljs-keyword\">const<\/span> post = data.nodeByUri;\n\n<span class=\"hljs-comment\">\/\/ Handle 404 case if no post is found<\/span>\n\n<span class=\"hljs-keyword\">if<\/span> (!post) {\n\n\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> Response(<span class=\"hljs-literal\">null<\/span>, { <span class=\"hljs-attr\">status<\/span>: <span class=\"hljs-number\">404<\/span> });\n\n}\n\n---\n\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span> <span class=\"hljs-attr\">lang<\/span>=<span class=\"hljs-string\">\"en\"<\/span>&gt;<\/span>\n\n\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>{post.title}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n\n\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n\n\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">article<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<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>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">time<\/span>&gt;<\/span>{new Date(post.date).toLocaleDateString()}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">time<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{post.featuredImage &amp;&amp; (\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{post.featuredImage.node.sourceUrl}<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{post.featuredImage.node.altText}<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{600}<\/span>\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">{400}<\/span>\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">\"fill\"<\/span>\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">gravity<\/span>=<span class=\"hljs-string\">\"auto\"<\/span>\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">quality<\/span>=<span class=\"hljs-string\">\"auto\"<\/span>\u00a0\n\n\/&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">set:html<\/span>=<span class=\"hljs-string\">{post.content}<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">article<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n\n\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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>This code block represents a dynamic route in an Astro project that generates individual post detail pages based on data fetched from WordPress using WPGraphQL and Cloudinary for image handling. Here&#8217;s a quick breakdown:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Imports:\n<ul class=\"wp-block-list\">\n<li><code>CldImage<\/code> from <code>astro-cloudinary<\/code> renders images from Cloudinary, with optimizations like dynamic cropping, resizing, and compression.<\/li>\n\n\n\n<li><code>getNodeByURI<\/code> and <code>getAllUris<\/code> from <code>..\/lib\/api<\/code> functions that query the WordPress GraphQL API to fetch posts and their associated URIs.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>getStaticPaths()<\/code>:\n<ul class=\"wp-block-list\">\n<li>This function tells Astro which paths to generate at build time. It fetches all the post URIs from WordPress and maps over them to generate static pages for each post. Each URI becomes a path for a dynamic route.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Fetching post data:\n<ul class=\"wp-block-list\">\n<li>The post&#8217;s URI is extracted from the route parameter (Astro.params.uri), and getNodeByURI is called with this URI to fetch the corresponding post data from WordPress.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>404 Handling<\/strong>:\n<ul class=\"wp-block-list\">\n<li>If no post is found for the given URI, a 404 response is returned to indicate that the page does not exist.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Rendering the Page<\/strong>:\n<ul class=\"wp-block-list\">\n<li>The page renders the post title, publication date, featured image (if available), and the post content.<\/li>\n\n\n\n<li><strong>CldImage<\/strong> is used to display the post&#8217;s featured image, pulling the image from Cloudinary and applying transformations (cropping, gravity, quality optimization).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>HTML Structure<\/strong>:\n<ul class=\"wp-block-list\">\n<li>The HTML structure includes a title, date, and the post content, all of which are dynamically populated based on the post data retrieved from WordPress.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Now when you visit the link on the home page, it should take you to a single post detail page like so:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1737686100\/Astro-Cloudinary_GIF.gif\" alt=\"\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>By following this guide, you\u2019ve successfully created a website using Astro and headless WordPress, enhanced by Cloudinary for efficient asset management. You\u2019ve connected WordPress with Astro using WPGraphQL, pulled in assets from Cloudinary, and displayed them on a dynamic Astro-powered site. This setup ensures your site is fast, responsive, and media-rich \u2014 perfect for modern web applications. <a href=\"https:\/\/cloudinary.com\/users\/register_free\">Sign up for a free Cloudinary account<\/a> and try it for yourself today.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Part 1, we\u2019ll set up WordPress as a headless CMS with WPGraphQL, grab our public ID data from our specific Cloudinary assets, and create the custom field in WordPress that is necessary to link the Cloudinary asset ID\u2019s to WordPress and Astro.&nbsp; In Part 2, we\u2019ll put everything together by creating an Astro app [&hellip;]<\/p>\n","protected":false},"author":87,"featured_media":36239,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,137,328],"class_list":["post-36234","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-headless","tag-wordpress"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)<\/title>\n<meta name=\"description\" content=\"In Part 1, we\u2019ll set up WordPress as a headless CMS with WPGraphQL, grab our public ID data from our specific Cloudinary assets, and create the custom\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)\" \/>\n<meta property=\"og:description\" content=\"In Part 1, we\u2019ll set up WordPress as a headless CMS with WPGraphQL, grab our public ID data from our specific Cloudinary assets, and create the custom\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-10-29T14:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-16T19:38:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"melindapham\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)\",\"datePublished\":\"2024-10-29T14:00:00+00:00\",\"dateModified\":\"2025-04-16T19:38:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2\"},\"wordCount\":1222,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Headless\",\"WordPress\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2024\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2\",\"url\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2\",\"name\":\"Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog.jpg?_i=AA\",\"datePublished\":\"2024-10-29T14:00:00+00:00\",\"dateModified\":\"2025-04-16T19:38:06+00:00\",\"description\":\"In Part 1, we\u2019ll set up WordPress as a headless CMS with WPGraphQL, grab our public ID data from our specific Cloudinary assets, and create the custom\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\",\"name\":\"melindapham\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"caption\":\"melindapham\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)","description":"In Part 1, we\u2019ll set up WordPress as a headless CMS with WPGraphQL, grab our public ID data from our specific Cloudinary assets, and create the custom","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:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2","og_locale":"en_US","og_type":"article","og_title":"Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)","og_description":"In Part 1, we\u2019ll set up WordPress as a headless CMS with WPGraphQL, grab our public ID data from our specific Cloudinary assets, and create the custom","og_url":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2","og_site_name":"Cloudinary Blog","article_published_time":"2024-10-29T14:00:00+00:00","article_modified_time":"2025-04-16T19:38:06+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog-jpg?_i=AA","type":"image\/jpeg"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)","datePublished":"2024-10-29T14:00:00+00:00","dateModified":"2025-04-16T19:38:06+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2"},"wordCount":1222,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog.jpg?_i=AA","keywords":["Guest Post","Headless","WordPress"],"inLanguage":"en-US","copyrightYear":"2024","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2","url":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2","name":"Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog.jpg?_i=AA","datePublished":"2024-10-29T14:00:00+00:00","dateModified":"2025-04-16T19:38:06+00:00","description":"In Part 1, we\u2019ll set up WordPress as a headless CMS with WPGraphQL, grab our public ID data from our specific Cloudinary assets, and create the custom","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/cloudinary-asset-loader-astro-headless-wordpress-wpgraphql-part-2#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Cloudinary Asset Loader for Astro and Headless WordPress Using WPGraphQL (Part 2)"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9","name":"melindapham","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","caption":"melindapham"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1729880223\/Assets_Loader_Astro_Headless_WordPress_p2-blog\/Assets_Loader_Astro_Headless_WordPress_p2-blog.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36234","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=36234"}],"version-history":[{"count":4,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36234\/revisions"}],"predecessor-version":[{"id":37429,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36234\/revisions\/37429"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/36239"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=36234"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=36234"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=36234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}