{"id":32,"date":"2025-07-01T14:24:37","date_gmt":"2025-07-01T18:24:37","guid":{"rendered":"https:\/\/www.shawntgray.com\/blog\/?p=32"},"modified":"2025-07-01T14:25:12","modified_gmt":"2025-07-01T18:25:12","slug":"how-to-build-an-art-gallery-with-react-part-1-get-started","status":"publish","type":"post","link":"https:\/\/www.shawntgray.com\/blog\/how-to-build-an-art-gallery-with-react-part-1-get-started\/","title":{"rendered":"How to Build an Art Gallery with React &#8211; Part 1: Get Started"},"content":{"rendered":"\n<p><strong>Dev Level:<\/strong> Beginner to Intermediate<br><strong>Tech Used:<\/strong> Git Bash, Visual Studio Basic, React JavaScript, CSS, NPM, Create React App, JSON<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-container-core-buttons-is-layout-cc423f81 wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/shawngraydesign.com\/react-gallery\" target=\"_blank\" rel=\"noreferrer noopener\">View Live Demo<\/a><\/div>\n\n\n\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/github.com\/ShawnBuildsSites\/react-image-gallery\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">GitHub Repo<\/a><\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>I always wanted a stylish, functional place for my random sketches, paintings and digital art. Something that is more permanent than any social media black hole. I also wanted a fun, engaging reason to learn how to build browser-based apps with React.<\/p>\n\n\n\n<p>So, with a little research, a good amount of trial &amp; error, and the patience and willpower to push through the usual &#8220;developer&#8217;s frustration&#8221;, I managed to build this project I can be just a little bit proud of.<\/p>\n\n\n\n<p>Here&#8217;s an example of what we&#8217;re building:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"923\" height=\"1024\" src=\"https:\/\/www.shawntgray.com\/blog\/wp-content\/uploads\/2025\/06\/full-page-screenshot-923x1024.webp\" alt=\"React Art Image Gallery full page\" class=\"wp-image-33\" srcset=\"https:\/\/www.shawntgray.com\/blog\/wp-content\/uploads\/2025\/06\/full-page-screenshot-923x1024.webp 923w, https:\/\/www.shawntgray.com\/blog\/wp-content\/uploads\/2025\/06\/full-page-screenshot-270x300.webp 270w, https:\/\/www.shawntgray.com\/blog\/wp-content\/uploads\/2025\/06\/full-page-screenshot-768x852.webp 768w, https:\/\/www.shawntgray.com\/blog\/wp-content\/uploads\/2025\/06\/full-page-screenshot-1385x1536.webp 1385w, https:\/\/www.shawntgray.com\/blog\/wp-content\/uploads\/2025\/06\/full-page-screenshot-1846x2048.webp 1846w, https:\/\/www.shawntgray.com\/blog\/wp-content\/uploads\/2025\/06\/full-page-screenshot.webp 1920w\" sizes=\"auto, (max-width: 923px) 100vw, 923px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Features<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Displays images in a flexible grid that responds cleanly to the user&#8217;s device.<\/li>\n\n\n\n<li>Details for each image (title, category tags, and image URL) are contained in a separate JSON file for easy editing.<\/li>\n\n\n\n<li>Each image contains a series of tags that can filter the gallery based on the tag selected.<\/li>\n\n\n\n<li>The gallery houses a full list of filter buttons. This list is dynamically built based on the tags listed under each image. These tags are alphabetized for easier readability.<\/li>\n\n\n\n<li>Click an image to view it in a full-screen lightbox style modal popup.<\/li>\n\n\n\n<li>For a bit of extra fun, the images are shuffled every time the gallery is loaded.<\/li>\n<\/ul>\n\n\n\n<p>This app also includes a dynamic slideshow that will be covered in a separate tutorial.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setup<\/h2>\n\n\n\n<p>For command-line actions, I use <a href=\"https:\/\/git-scm.com\/downloads\" target=\"_blank\" rel=\"noopener nofollow\" title=\"\">Git Bash<\/a> and <a href=\"https:\/\/docs.npmjs.com\/downloading-and-installing-node-js-and-npm\" target=\"_blank\" rel=\"noopener nofollow\" title=\"\">Node Package Manager (NPM)<\/a> inside <a href=\"https:\/\/code.visualstudio.com\/download\" target=\"_blank\" rel=\"noopener nofollow\" title=\"\">Visual Studio Code<\/a>. With these 3 installed, open Visual Studio Code, access a Git Bash Terminal, and enter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm -v<\/code><\/pre>\n\n\n\n<p>This command ensures you have npm installed. Then, navigate to the directory where you want your project to live.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd path\/to\/folder<\/code><\/pre>\n\n\n\n<p>I chose to use the <a href=\"https:\/\/create-react-app.dev\/docs\/getting-started\/\" target=\"_blank\" rel=\"noopener nofollow\" title=\"\">Create React App<\/a> package for this project. This option is perfect for single-page React apps with little to no unnecessary bloat or overhead. Vite, Vue, and others are a bit too bulky for what we&#8217;re building.<\/p>\n\n\n\n<p>Start your project by typing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install -g create-react-app\nnpm create-react-app react_art_gallery\ncd react_art_gallery<\/code><\/pre>\n\n\n\n<p>Create React App will build a starter version of your project with a directory that would look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>react_art_gallery\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 node_modules\n\u251c\u2500\u2500 package.json\n\u251c\u2500\u2500 .gitignore\n\u251c\u2500\u2500 public\n\u2502   \u251c\u2500\u2500 favicon.ico\n\u2502   \u251c\u2500\u2500 index.html\n\u2502   \u251c\u2500\u2500 logo192.png\n\u2502   \u251c\u2500\u2500 logo512.png\n\u2502   \u251c\u2500\u2500 manifest.json\n\u2502   \u2514\u2500\u2500 robots.txt\n\u2514\u2500\u2500 src\n    \u251c\u2500\u2500 App.css\n    \u251c\u2500\u2500 App.js\n    \u251c\u2500\u2500 App.test.js\n    \u251c\u2500\u2500 index.css\n    \u251c\u2500\u2500 index.js\n    \u251c\u2500\u2500 logo.svg\n    \u251c\u2500\u2500 serviceWorker.js\n    \u2514\u2500\u2500 setupTests.js<\/code><\/pre>\n\n\n\n<p>Next, <strong>remove the unnecessary files.<\/strong><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p class=\"has-primary-color has-text-color has-link-color wp-elements-168c18b01696ee0bcac2ea2a4a386265\"><strong>public folder<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>logo192.png<\/li>\n\n\n\n<li>logo512.png<\/li>\n\n\n\n<li>manifest.json<\/li>\n\n\n\n<li>robots.txt<\/li>\n<\/ul>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p class=\"has-primary-color has-text-color has-link-color wp-elements-b1f7634c72c82dcc62e0e406c0e2442d\"><strong>src folder<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>App.test.js<\/li>\n\n\n\n<li>logo.svg<\/li>\n\n\n\n<li>serviceWorker.js<\/li>\n\n\n\n<li>setupTests.js<\/li>\n<\/ul>\n<\/div>\n<\/div>\n\n\n\n<p>Add an <strong>images<\/strong> folder to the <strong>public <\/strong>folder. This is where you will place all the images you want displayed in your gallery.<\/p>\n\n\n\n<p>To make this project even more uniquely your own, be sure to replace the <strong>favicon.ico<\/strong> with your logo or symbol.<\/p>\n\n\n\n<p>Now your project directory should look similar to this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>react_art_gallery\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 node_modules\n\u251c\u2500\u2500 package.json\n\u251c\u2500\u2500 .gitignore\n\u251c\u2500\u2500 public\n\u2502   \u2514\u2500\u2500 images\n\u2502   \u2502   \u2514\u2500\u2500 <em>all your images go here<\/em>\n\u2502   \u251c\u2500\u2500 favicon.ico\n\u2502   \u2514\u2500\u2500 index.html\n\u2514\u2500\u2500 src\n    \u2514\u2500\u2500 App.css\n    \u251c\u2500\u2500 App.js\n    \u251c\u2500\u2500 index.css\n    \u2514\u2500\u2500 index.js<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next?<\/h2>\n\n\n\n<p>We will first set up the JSON file that will hold the data that will be fed into the gallery app. Then, we will begin building the app&#8217;s several components and styling each component with its own CSS.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to build a fully responsive filterable image gallery with React Javascript and CSS. Perfect for artistic portfolios and unique photo albums!<\/p>\n","protected":false},"author":1,"featured_media":34,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[9],"tags":[],"class_list":["post-32","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-art-gallery"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/posts\/32","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/comments?post=32"}],"version-history":[{"count":3,"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/posts\/32\/revisions"}],"predecessor-version":[{"id":42,"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/posts\/32\/revisions\/42"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/media\/34"}],"wp:attachment":[{"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/media?parent=32"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/categories?post=32"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shawntgray.com\/blog\/wp-json\/wp\/v2\/tags?post=32"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}