{"id":28322,"date":"2021-04-14T17:23:07","date_gmt":"2021-04-14T17:23:07","guid":{"rendered":"http:\/\/Serving-Remote-Images-in-Gatsby.js-using-Gatsby-image-wo-GraphQL"},"modified":"2025-04-16T13:30:41","modified_gmt":"2025-04-16T20:30:41","slug":"serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/","title":{"rendered":"Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>You probably want to use a hosted image with Gatsby-image in your Gatsby.js project. You don\u2019t need to have this image stored locally, and you won\u2019t need to fetch it with a GraphQL query. We\u2019ll see how in this jam.<\/p>\n<p><a href=\"https:\/\/codesandbox.io\/s\/using-remote-images-in-gatsby-w-gatsby-image-live-yqhxq\">Part 1 of this project<\/a> chronicles using remote images from Cloudinary in Gatsby.js projects through GraphQL queries. In this part, we\u2019ll discuss how to \u2014<\/p>\n<ul>\n<li>Utilize a remote image stored on Cloudinary with gatsby-image.<\/li>\n<li>Serve fluid or fixed images with gatsby-image without a GraphQL query.<\/li>\n<li>Render optimized, responsive images with gatsby-image.<\/li>\n<li>Transform those images with Cloudinary.<\/li>\n<\/ul>\n<p><strong>You don\u2019t need to read part 1 to go through this post.<\/strong><\/p>\n<h2>Sandbox<\/h2>\n<p>We completed this project in <a href=\"https:\/\/codesandbox.io\/s\/using-remote-images-in-gatsby-w-gatsby-image-5qtpi?file=\/.env.example\">a Codesandbox, and you can fork it<\/a> to see all the code in action. To use the sandbox, you need to create a .env file, and add your Cloudinary API key and secret. Follow the format specified in the <code>.env.example<\/code> in the root directory of the projects.<\/p>\n<blockquote>\n<p>Suppose you don\u2019t need to upload local images to your Cloudinary account. In that case you don\u2019t need to specify your API key and secret in the plugin configuration.<\/p>\n<\/blockquote>\n<p><a href=\"https:\/\/codesandbox.io\/s\/using-remote-images-in-gatsby-w-gatsby-image-5qtpi?file=\/.env.example\">https:\/\/codesandbox.io\/s\/using-remote-images-in-gatsby-w-gatsby-image-5qtpi?file=\/.env.example<\/a><\/p>\n<p>We have an image on Cloudinary which we will source and transform from<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/scotch-res.cloudinary.com\/image\/upload\/dpr_1,w_800,q_auto:good,f_auto\/c_limit,w_2000\/f_auto\/q_auto\/v1588831184\/hp6dztpsu6phk25ng5sp.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\" \/><\/p>\n<p>to<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_4D5D4DEF3AB18457128537E149C288783D57DB84DB71AC7152CB14A505292016_1613824282338_image.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"800\" height=\"652\"\/><\/p>\n<p>Specifically, this post guides you through two processes:<\/p>\n<ol>\n<li>\n<p>Fetch an image from Cloudinary with the <code>getFluidImageObject<\/code> API of gatsby-transformer-cloudinary and render that image with gatsby-image. You can fetch any image from your Cloudinary account. Also, even after applying the Cloudinary transformations that you specify, the API optimizes that image with gatsby-image during the build process.<\/p>\n<\/li>\n<li>\n<p>Create a user interface and typography with <a href=\"https:\/\/chakra-ui.com\/\">Chakra-ui<\/a>.<\/p>\n<\/li>\n<\/ol>\n<h2>Project Installation<\/h2>\n<p>We implement this feature on an existing Gatsby.js project. You can fork <a href=\"https:\/\/codesandbox.io\/s\/using-remote-images-in-gatsby-w-gatsby-image-bare-c0p7r?file=\/src\/pages\/index.js\">this base Codesandbox<\/a> containing the dependencies installed, configuration, and layout. Otherwise, we install Gatsby.js globally and create a new project with<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">     npm install -g gatsby-cli &amp;&amp; gatsby <span class=\"hljs-keyword\">new<\/span> gtc-demo\n<\/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<p>We proceed to install the required dependencies with<\/p>\n<pre><code>cd gtc-demo &amp;&amp; npm i --save gatsby-transformer-cloudinary dotenv @chakra-ui\/gatsby-plugin @chakra-ui\/react @emotion\/react @emotion\/styled framer-motion \n<\/code><\/pre>\n<h2>Project setup<\/h2>\n<p><a href=\"https:\/\/bit.ly\/2v3sy4N\">Sign up for a Cloudinary account<\/a>. Cloudinary offers a free tier, which is more than adequate for small to medium projects.\nOnce signed up, note your cloud name, API key, and API secret for later use.<\/p>\n<p>With the required dependencies installed, we need to configure the gatsby plugins in <code>gatsby-config.js<\/code> &#8211; a Gatsby file in the project\u2019s root directory to manage plugin configurations.<\/p>\n<p>First, we import <em>dontenv<\/em>, a required dependency to setup environment variables. Also, we update the site meta data to match the current project.<\/p>\n<pre class=\"js-syntax-highlighted\" 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-built_in\">require<\/span>(<span class=\"hljs-string\">\"dotenv\"<\/span>).config()\n    <span class=\"hljs-built_in\">module<\/span>.exports = {\n      <span class=\"hljs-attr\">siteMetadata<\/span>: {\n        <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">`Gatsby x Cloudinary`<\/span>,\n        <span class=\"hljs-attr\">description<\/span>: <span class=\"hljs-string\">`Serve remote images in your Gatsby app using gatsby-image`<\/span>,\n        <span class=\"hljs-attr\">author<\/span>: <span class=\"hljs-string\">`@gatsbyjs`<\/span>\n      },\n\t\t}\n\t\t\t\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<p>Next, we configure installed plugins including react-helmet, gatsby-source-filesystem, @chakra-ui\/gatsby-plugin and gatsby-transformer-cloudinary.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\t<span class=\"hljs-built_in\">module<\/span>.exports = {\n\t\t\t{other config goes <span class=\"hljs-keyword\">in<\/span> here},\n\t\n      <span class=\"hljs-attr\">plugins<\/span>: &#91;\n        <span class=\"hljs-string\">`gatsby-plugin-react-helmet`<\/span>,\n        {\n          <span class=\"hljs-attr\">resolve<\/span>: <span class=\"hljs-string\">`gatsby-source-filesystem`<\/span>,\n          <span class=\"hljs-attr\">options<\/span>: {\n            <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">`cloudinary-images`<\/span>,\n            <span class=\"hljs-attr\">path<\/span>: <span class=\"hljs-string\">`<span class=\"hljs-subst\">${__dirname}<\/span>\/src\/remote-images`<\/span>\n          }\n        },\n        {\n          <span class=\"hljs-attr\">resolve<\/span>: <span class=\"hljs-string\">\"@chakra-ui\/gatsby-plugin\"<\/span>,\n          <span class=\"hljs-attr\">options<\/span>: {\n            <span class=\"hljs-attr\">isUsingColorMode<\/span>: <span class=\"hljs-literal\">true<\/span>\n          }\n        },\n        {\n          <span class=\"hljs-attr\">resolve<\/span>: <span class=\"hljs-string\">\"gatsby-transformer-cloudinary\"<\/span>,\n          <span class=\"hljs-attr\">options<\/span>: {\n            <span class=\"hljs-attr\">cloudName<\/span>: process.env.CLOUDINARY_CLOUD_NAME,\n            <span class=\"hljs-attr\">apiKey<\/span>: process.env.CLOUDINARY_API_KEY,\n            <span class=\"hljs-attr\">apiSecret<\/span>: process.env.CLOUDINARY_API_SECRET,\n            <span class=\"hljs-attr\">uploadFolder<\/span>: <span class=\"hljs-string\">\"gtc-art-gallery\"<\/span>\n          }\n        }\n      ]\n    }\n<\/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<p>In the configuration file, gatsby-source-filesystem, a source plugin, sources file nodes into the Gatsby data layer. Here, we\u2019ve sourced all the images in a folder, which are uploaded once to Cloudinary on build.<\/p>\n<p>We created the <code>remote-images<\/code> folder in the <code>src<\/code> directory of the project. We uploaded all the images into the folder.<\/p>\n<p>We proceed to create a .env file in the project\u2019s root directory, and add our Cloudinary credentials as specified below:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">    <span class=\"hljs-comment\"># Find this at https:\/\/cloudinary.com\/console\/settings\/account<\/span>\n    CLOUDINARY_CLOUD_NAME=xxxxx\n    \n    <span class=\"hljs-comment\"># Generate an API key pair at https:\/\/cloudinary.com\/console\/settings\/security<\/span>\n    CLOUDINARY_API_KEY=xxxxxxxxxxxxxx\n    CLOUDINARY_API_SECRET=xxxxxxxxxxxxxxxxxxx\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Next, we start the development server on <code>localhost:8000<\/code> by running the command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    gatsby develop\n<\/code><\/span><\/pre>\n<p>All the images in the remote-images folder are uploaded to Cloudinary and added to file nodes for the returned URLs are created in Gatsby\u2019s GraphQL layer.<\/p>\n<h2>Image fetching with getFluidImageObject and getFixedImageObject<\/h2>\n<p>Even though both <code>getfluidImageObject<\/code> and <code>getFixedImageObject<\/code> fetch images from Cloudinary accounts with multiple or chained transformations, the two APIs vary as follows:<\/p>\n<p><code>getFluidImageObject<\/code> returns a fluid image object with the breakpoints you specified. If you did not set any, it returns breakpoints with a maximum width of 1000.<\/p>\n<p><code>getFixedImageObject<\/code> returns a fixed-width image object.<\/p>\n<p>Passing the response from the asynchronous calls of the functions to the <code>fluid<\/code> or <code>fixed<\/code> property of the gatsby-image <code>&lt;Image\/&gt;<\/code> component renders the image.\nBoth APIs fetch images with a single asynchronous operation, hence no need for GraphQL queries.<\/p>\n<h2>Page creation for a single image<\/h2>\n<p>We create a webpage that contains an image fetched with <code>getFluidImageObject<\/code>. We apply the same layout from <a href=\"https:\/\/github.com\/Chuloo\/gtc-demo\/tree\/part-1\">part 1<\/a> (you can use any layout).<\/p>\n<p>Gatsby.js builds pages from the JavaScript (JS) files in the src\/pages directory.<\/p>\n<p>We do the following:<\/p>\n<ol>\n<li>\n<p>Create a JavaScript file titled <code>single.js<\/code> in <code>src\/pages<\/code>. Gatsby.js adds <code>single.js<\/code> to the route <code>\/single<\/code>.<\/p>\n<\/li>\n<li>\n<p>Import the required modules into single.js with this code:<\/p>\n<\/li>\n<\/ol>\n<pre class=\"js-syntax-highlighted\" 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-keyword\">import<\/span> React, { useEffect, useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>\n    <span class=\"hljs-keyword\">import<\/span> Layout <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/components\/layout\"<\/span>\n    <span class=\"hljs-keyword\">import<\/span> { getFluidImageObject } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"gatsby-transformer-cloudinary\/api\"<\/span>\n    <span class=\"hljs-keyword\">import<\/span> Image <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"gatsby-image\"<\/span>\n    <span class=\"hljs-keyword\">import<\/span> { Box, Heading, Text } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@chakra-ui\/react\"<\/span>;\n<\/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<ol start=\"3\">\n<li>Create and export a functional component titled <code>SinglePage<\/code>. In the function, fetch a single <a href=\"https:\/\/cloudinary.com\/products\/image\">Cloudinary image<\/a> with a public ID of your choice. Below is the code, in which the public ID is <code>gatsby-source-cloudinary\/penguin<\/code>:<\/li>\n<\/ol>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" 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> SinglePage = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-keyword\">const<\/span> &#91;fluid, setFluid] = useState(<span class=\"hljs-literal\">undefined<\/span>)\n    \n      useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getData<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n          <span class=\"hljs-keyword\">const<\/span> res = <span class=\"hljs-keyword\">await<\/span> getFluidImageObject({\n            <span class=\"hljs-attr\">public_id<\/span>: <span class=\"hljs-string\">\"gatsby-source-cloudinary\/penguin\"<\/span>,\n            <span class=\"hljs-attr\">cloudName<\/span>: <span class=\"hljs-string\">\"chuloo\"<\/span>,\n            <span class=\"hljs-attr\">originalHeight<\/span>: <span class=\"hljs-number\">400<\/span>,\n            <span class=\"hljs-attr\">originalWidth<\/span>: <span class=\"hljs-number\">500<\/span>,\n            <span class=\"hljs-attr\">maxWidth<\/span>: <span class=\"hljs-number\">800<\/span>,\n            <span class=\"hljs-attr\">transformations<\/span>: &#91;<span class=\"hljs-string\">\"e_replace_color:purple\"<\/span>, <span class=\"hljs-string\">\"a_hflip\"<\/span>, <span class=\"hljs-string\">\"f_auto\"<\/span>, <span class=\"hljs-string\">\"q_auto\"<\/span>],\n          })\n          setFluid(res)\n        }\n    \n        getData()\n      }, &#91;])\n    \n\t\t<span class=\"hljs-keyword\">return<\/span> (\n\t\t\t<span class=\"hljs-comment\">\/\/ return statement goes here<\/span>\n\t\t)\n  }\n    \n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> SinglePage\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<p>In the above code, <code>getFluidImageObject<\/code> is an asynchronous function called on page load using <code>useEffect<\/code>. Once that function returns the image object, we store it in the component\u2019s <code>fluid<\/code> state with useState.<\/p>\n<p>Next, we pass the following keys to <code>getFluidImageObjects<\/code> in its object argument:<\/p>\n<ul>\n<li>\n<strong>public<\/strong>_<strong>id<\/strong>: The public ID of the Cloudinary image<\/li>\n<li>\n<strong>cloudName<\/strong>: The cloud name of your Cloudinary account<\/li>\n<li>\n<strong>originalHeight<\/strong>: The height of the image to be fetched<\/li>\n<li>\n<strong>originalWidth<\/strong>: The width of the image to be fetched<\/li>\n<li>\n<strong>transformations<\/strong>: The transformations Cloudinary applies to the returned image<\/li>\n<\/ul>\n<p>See <a href=\"https:\/\/www.npmjs.com\/package\/gatsby-transformer-cloudinary#api\">the complete keys<\/a> along with their optional, and required, arguments.<\/p>\n<p><code>getFluidImageObject<\/code> passes Cloudinary transformations in the transformation\u2019s key to add a purple effect, horizontally flip the image with <code>e_replace_color:purple<\/code> and <code>a_hflip<\/code>, and apply optimization transformations for quality and format.<\/p>\n<blockquote>\n<p>With getFluidImageObjects, you can fetch with gatsby-image any image in your Cloudinary account for display on the page.<\/p>\n<\/blockquote>\n<p>Gatsby-image lazy-loads images that we sourced and transformed with <code>getFluidImageObject<\/code>.<\/p>\n<p>In the <code>SinglePage<\/code> component, we\u2019ll proceed to return the JSX elements to render the page. The global layout is used, <code>&lt;SEO\/&gt;<\/code> element to provide search engine optimization data for the page, and the gatsby-image <code>&lt;Image\/&gt;<\/code> component to render the fluid image data returned by <code>getFluidImageObjects<\/code>.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Layout<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">SEO<\/span> <span class=\"hljs-attr\">title<\/span>=<span class=\"hljs-string\">{<\/span>\"<span class=\"hljs-attr\">single<\/span>\"} \/&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Box<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Heading<\/span> <span class=\"hljs-attr\">as<\/span>=<span class=\"hljs-string\">{<\/span>\"<span class=\"hljs-attr\">h1<\/span>\"} <span class=\"hljs-attr\">size<\/span>=<span class=\"hljs-string\">{<\/span>\"<span class=\"hljs-attr\">lg<\/span>\"} <span class=\"hljs-attr\">m<\/span>=<span class=\"hljs-string\">{5}<\/span> <span class=\"hljs-attr\">textAlign<\/span>=<span class=\"hljs-string\">{<\/span>\"<span class=\"hljs-attr\">center<\/span>\"}&gt;<\/span>\n              Single Fluid Image\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Heading<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Box<\/span>\n              <span class=\"hljs-attr\">maxWidth<\/span>=<span class=\"hljs-string\">{&#91;350,<\/span> <span class=\"hljs-attr\">400<\/span>, <span class=\"hljs-attr\">500<\/span>]}\n              <span class=\"hljs-attr\">mx<\/span>=<span class=\"hljs-string\">{<\/span>\"<span class=\"hljs-attr\">auto<\/span>\"}\n              <span class=\"hljs-attr\">shadow<\/span>=<span class=\"hljs-string\">\"md\"<\/span>\n              <span class=\"hljs-attr\">borderWidth<\/span>=<span class=\"hljs-string\">\"1px\"<\/span>\n              <span class=\"hljs-attr\">rounded<\/span>=<span class=\"hljs-string\">{<\/span>\"<span class=\"hljs-attr\">lg<\/span>\"}\n              <span class=\"hljs-attr\">p<\/span>=<span class=\"hljs-string\">{3}<\/span>\n            &gt;<\/span>\n              {fluid ? <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Image<\/span> <span class=\"hljs-attr\">fluid<\/span>=<span class=\"hljs-string\">{fluid}<\/span> \/&gt;<\/span> : \"loading...\"}\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Box<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Box<\/span> <span class=\"hljs-attr\">my<\/span>=<span class=\"hljs-string\">{30}<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Text<\/span>&gt;<\/span>\n                This is a single image sourced directly from Cloudinary. This image\n                can be any image in your Cloudinary account, the public ID of the\n                image is required to source this images for use in gatsby-image{\" \"}\n              <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Text<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Box<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Box<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Layout<\/span>&gt;<\/span><\/span>\n)\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><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<p>Chakra-ui styles the components for a responsive layout and responsive typography in the above code, with breakpoints for mobile, tablet, and desktop.<\/p>\n<p>Now we restart the development server for the updated look of the webpage.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_4D5D4DEF3AB18457128537E149C288783D57DB84DB71AC7152CB14A505292016_1613828004449_image.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"767\" height=\"788\"\/><\/p>\n<h2>Summary<\/h2>\n<p>You now know how to fetch images with <code>getFluidImageObject<\/code> from Cloudinary into gatsby-image for Gatsby.js projects. <code>getFixedImageObject<\/code> conveys fixed images for gatsby-image in a similar manner.<\/p>\n<p>Coming up is part 3, which describes how to add a dark mode as a toggle for the website and convert it to a progressive web app (PWA) with only a few code lines. Pretty amazing.<\/p>\n<p>You can find the links below useful<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/www.npmjs.com\/package\/gatsby-transformer-cloudinary\">Gatsby-transformer-cloudinary<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/chakra-ui.com\/docs\/getting-started\">Chakra-ui Documentation<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/reactjs.org\/docs\/getting-started.html\">React.js Documentation<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28323,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[378,134,175,371],"class_list":["post-28322","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-gatsbyjs","tag-guest-post","tag-jamstack","tag-under-review"],"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>Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL<\/title>\n<meta name=\"description\" content=\"In this jam, we discussed how to use remote images from Cloudinary in a Gatsby project using gatsby-image and without the need for Grapql image queries.\" \/>\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\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL\" \/>\n<meta property=\"og:description\" content=\"In this jam, we discussed how to use remote images from Cloudinary in a Gatsby project using gatsby-image and without the need for Grapql image queries.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-04-14T17:23:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-16T20:30:41+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL\",\"datePublished\":\"2021-04-14T17:23:07+00:00\",\"dateModified\":\"2025-04-16T20:30:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/\"},\"wordCount\":11,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA\",\"keywords\":[\"GatsbyJS\",\"Guest Post\",\"JAMStack\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/\",\"name\":\"Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA\",\"datePublished\":\"2021-04-14T17:23:07+00:00\",\"dateModified\":\"2025-04-16T20:30:41+00:00\",\"description\":\"In this jam, we discussed how to use remote images from Cloudinary in a Gatsby project using gatsby-image and without the need for Grapql image queries.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA\",\"width\":4896,\"height\":3264},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL\"}]},{\"@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\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL","description":"In this jam, we discussed how to use remote images from Cloudinary in a Gatsby project using gatsby-image and without the need for Grapql image queries.","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\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/","og_locale":"en_US","og_type":"article","og_title":"Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL","og_description":"In this jam, we discussed how to use remote images from Cloudinary in a Gatsby project using gatsby-image and without the need for Grapql image queries.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/","og_site_name":"Cloudinary Blog","article_published_time":"2021-04-14T17:23:07+00:00","article_modified_time":"2025-04-16T20:30:41+00:00","twitter_card":"summary_large_image","twitter_image":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/"},"author":{"name":"","@id":""},"headline":"Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL","datePublished":"2021-04-14T17:23:07+00:00","dateModified":"2025-04-16T20:30:41+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/"},"wordCount":11,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA","keywords":["GatsbyJS","Guest Post","JAMStack","Under Review"],"inLanguage":"en-US","copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/","name":"Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA","datePublished":"2021-04-14T17:23:07+00:00","dateModified":"2025-04-16T20:30:41+00:00","description":"In this jam, we discussed how to use remote images from Cloudinary in a Gatsby project using gatsby-image and without the need for Grapql image queries.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA","width":4896,"height":3264},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/serving-remote-images-in-gatsby-js-using-gatsby-image-wo-graphql\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Serving Remote Images in Gatsby.js using Gatsby-image w\/o GraphQL"}]},{"@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":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924817\/Web_Assets\/blog\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59\/a27f11ceb2d9c7efb8d591048b09e8c3fd38226f-4896x3264-1_283235ee59.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28322","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\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=28322"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28322\/revisions"}],"predecessor-version":[{"id":37450,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28322\/revisions\/37450"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28323"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28322"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28322"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28322"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}