Home page search results image cards
VisualGrid is a client-side web app for visual project planning and goal-setting. Users can search the Unsplash API, save images to a personalized board, and attach notes or goal statements to each item. The app includes modal image views, a full-screen slider, localStorage persistence, and tools for organizing, annotating, and revisiting saved images.
- Clone this repo and install dependencies:
# Clone this repo
git clone https://github.com/Kernix13/vision-grid-express.git
# Change into project directory
cd vision-grid-express
# Install dependencies
npm install
# Open the project in VS Code
code .- Create a
.envfile in the project root. - Copy the lines in
.env.exampleand paste them into your newly created.envfile.
CLIENT_ID=your_unsplash_client_id
PORT=port_number- Replace the string
your_unsplash_client_idwith your Unsplash API Client ID, andport_numberto ``8080` or with the port you want to use. - Delete the file
.env.example. - Start the development server:
npm run dev- CTRL + click the link
http://localhost:8080in the terminal to open uplocalhoston port8080:
Server is running http://localhost:8080You can now search for images, save images to your board page, add notes for each saved image, etc.
- (OPTIONAL): Run Biome for linting and formatting checks on your files:
npm run check- Go to the Unsplash website & click the hamburger icon in the top right.
- Under the Product heading click Developers/API which takes you to Unsplash Developers.
- Click the button labeled "Register as a developer".
- Fill out the form and click Join to register your account: first name, last name, email address, username, and password.
- Click the button labeled "You apps".
- Click the box with the text "New Application".
- Under the heading "API Use and Guidelines", check all of the checkboxes, Read the Terms of Use documentation then click Accept terms.
- You are presented with a popup asking to enter an Application name and Description. Enter a name and description then click "Create application".
- Go to your application's detail page by clicking on your app name. You can get there by clicking Your apps on the developers main page.
- Scroll down to the Keys section that displays application id, access key, and secret key. The access key is the API key that you will need for this project
- NOTE: During this process you will be sent an email to the email address you entered above. Click the link in the email to "Confirm your account". You also may need to go back to the developers page and "Your apps" again to get to your Keys.
Home page image modal with Save, Remove and navigation buttons
- Image Search
- Enter a search phrase to fetch 12 images from the Unsplash API.
- Past search terms are saved and can be revisited, each automatically loading the next page of results.
- Image Cards
- View each image in compact form in the cards that are created from your search.
- Save or remove images directly from the cards.
- Click any image to view a larger, aspect-correct version in a modal.
- Modal Viewer
- Navigate through all images currently loaded on the page.
- You can also save or remove images from within the modal.
- Load More
- The "Load More" button fetches the next page of images for the current search.
Board page thumbnails strip on right & image with editable text field
- Saved Images Display
- View all saved images in a large, clean layout.
- Each image includes an editable text area for notes persisted via localStorage.
- Thumbnail Strip
- See all saved items in a compact strip for quick navigation.
- Clicking on any thumbnail takes you to that image on the page.
- Reorder saved images by moving them up or down.
- Delete images and their notes from your project.
- Choose to show or hide the image in the lightbox slider (WIP)
- Click the page image or editable text box to close the thumbnail strip.
- Affirmation / Goal Statement
- Click any saved image on the page to open a modal with a larger view.
- Add an affirmation or goal statement for that image (115-character limit).
- Navigate to other saved images within the modal to quickly update each affirmation.
- These affirmations are shown in the full-screen slider instead of your page notes.
- Lightbox Slider
- A full-screen modal that cycles through saved images.
- The slider also displays the image's affirmation/goal statement created in the modal.
- Adjustable timing between slides (6, 8, 10, 15 or 20 seconds).
This is the current state of my project as of December 17th, 2025:
/
├── README.md
├── assets/ # Images used in README only
├── LICENSE
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── biome.json # Biome formatter, linter, and code-quality config
├── package.json # Dependencies and scripts
├── server.js # Express server handling API requests
├── .env.example # Template for required environment variables in .env
├── .gitattributes # Enforces consistent line endings and other Git settings
├── .gitignore # Specific files and folders Git should ignore
├── .github/ # GitHub Issue and PR templates
├── public/
│ ├── index.html
│ ├── board.html
│ ├── about.html
│ ├── robots.txt
│ ├── sitemap.xml
│ ├── css/
│ ├── js/
│ │ ├── index.js # Main file for index.html
│ │ ├── board.js # Main file for board.html
│ │ ├── about.js # Main file for about.html
│ │ ├── api/ # Fetch function(s) for backend /api/photos
│ │ ├── ui/ # UI behavior functions
│ │ └── utils/ # Shared/utility functions
│ ├── images/
│ └── fonts/ # DM Sans and Inter .woff2 files- Integrate an API into your project: Fetch images from the Unsplash API:
/api/photos - At least one media query: 8 different media query breakpoints across 5 CSS files
- Have at least two pages/routes:
index.html,board.html,about.html
| Requirement | Implementation |
|---|---|
| Analyze data that is stored in various data structures | Retrieve API JSON, save as localStorage objects and strings, used in many functions |
Create a function with 2 or more params with a return value |
|
| Display information about the data in your app |
|
| Persist data to local storage, display/use that data |
|
| TABLE 2: Create a Node.js web server using Express.js | Express server with 2 query parameters and middleware |
Contributions are welcome! If you'd like to help improve this project, please read our CONTRIBUTING.md for guidelines on how to get started, our workflow, and code style expectations.
- Add a confirmation modal for the "clear all" button
- Add an option for the user to remove all saved images
- Allow user to uncheck showing any saved image in the lightbox slider
- Save everything to a MySQL database instead of
localStorage - Allow user to fetch only landscape, portrait, or square-ish image formats
- Use
srcsetfor DOM images on different devices for improved performance - Allow the user to have more than one board
- Get the image slider to go full-screen
- Dark/Light mode option
- Add a quote generator API that pairs an inspirational quote with each image
- Add a music API for motivational music during lightbox slideshow
I asked ChatGPT for help on project ideas. I gave it a list of my hobbies/interests and its Unsplash idea was the most interesting to me.
ChatGPT writes better copy than I do so I asked it to write some of the text in my README and for my HTML pages.
- It generated the "Project Structure" directory tree block above.
- I had boilerplate for
CONTRIBUTING.mdfrom previous projects. It wrote the content I have in there now for this project and the paragraph of text for that section. - I asked ChatGPT about including a
.env.sampleor.env.examplefile. It told me that.env.examplewas more commonly used so I created that file. - ChatGPT gave me an outline for the "How it Works" section
- I asked ChatGPT about including
robots.txtandsitemap.xmlfiles. It suggested to add them and wrote the contents forsitemap.xml. - ChatGPT edited some of my bullet points in my Tech Stack section, and wrote the points for the tech I am unfamilar with (Node, npm, and Express)
- ChatGPT wrote the H1 title and H2 sub-title for index.html.
- It wrote the H2 heading in the footer.
- On the About page, it wrote the text for the Intro, Quick Start, and Tips & Best Practices sections. It also edited/revised my bullet points in the other sections on about.html.
- ChatGPT helped me with the code to "contain" the images in the image cards, specifically using
aspect-ratioandobject-fit:
.result-image {
aspect-ratio: 1 / 1;
object-fit: cover;
}- Although I was able to save the
contenteditabletext tolocalStorage, I could not figure out how to preserve line breaks. ChatGPT suggestedinnerHTML:
// in boardEvents.js > saveUserText:
imgObj.notes = editable.innerHTML.trim();
// in savedImages.js > addSavedImagesToDom:
p.innerHTML = img.notes || 'You can add or edit notes here...';The following resources were helpful during the design and development process
Code/Technical:
- Code:You module lesson material, suggested videos, and Q&A in Slack.
- MDN CSS Docs for syntax and examples for JavaScript, CSS, and some HTML attributes.
- Traversy Media Discord server: help with npm packages, specifically Biome.
- Express Crash Course by Traversy Media: Specifically using
req.queryinserver.js. - React Full Course for free 2024 - BroCode: his example of array destructuring for moving To-Do items was what I needed for reordering saved images on the board page.
- Google DevTools Lighthouse reports for finding and fixing Performance and Accessibility issues.
- JavaScript30 course by Wes Bos: Day 1, JavaScript Drum Kit video on using the
transitionendevent type for my transitions for the image card removals. - Guide to Finding Closest Target: This was useful for the issues I was having handling event delegation.
Design & UI:
- Traversy Media Favicon Generator for generating my favicons.
- Gary Simon UI Design Course for design fundamentals, and component & layout design.
- Kevin Powell videos on CSS Grid, modals, and many other useful CSS properties.
- Google Fonts: Downloaded the
woff2files for DM Sans, Inter, and Allura. - What Font Chrome extension for verifying that my Google fonts were loading, and checking the displayed font size and weight for elements.
- Bootstrap icons for SVG icons used on each HTML page.
Accessibility:
- WebAim Contrast Checker for making color palette choices.
- VisBug Chrome extension for quickly checking contrast ratio for page elements.
- WAVE Evaluation Tool Chrome extension for a web accessibility report on my pages.
This project is licensed under the MIT License.
