How to Add an Image from a Folder in HTML
Learn the correct relative image path in HTML, fix missing images, and make folder-based images accessible and reliable in production.
Put the image in a folder relative to your HTML file, then use that folder path in the src attribute:
<img src="images/photo.jpg" alt="Description of the photo">
The path is a URL relative to the HTML document’s location. It is not a path to a folder on your computer. The alt text describes the image for accessibility and appears when the image cannot load. See MDN’s guidance on the <img> element.
1. Use the right folder structure
For an index.html file and an images folder next to it, use a child-folder path:
website/
├── index.html
└── images/
└── photo.jpg
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Photo</title>
</head>
<body>
<img src="images/photo.jpg"
alt="A description of the photo"
width="800"
height="600"
loading="lazy"
decoding="async">
</body>
</html>
images/photo.jpg means “open the images directory below the directory containing this HTML document, then request photo.jpg.”
2. Choose the path for your layout
| HTML file | Image file | src value |
|---|---|---|
index.html |
images/photo.jpg |
images/photo.jpg |
pages/about.html |
images/photo.jpg in the project root |
../images/photo.jpg |
index.html |
photo.jpg beside it |
photo.jpg |
pages/about.html |
pages/images/photo.jpg |
images/photo.jpg |
Add one ../ segment for each directory level you must move upward. For example, from articles/2026/post.html to a root-level images folder, use ../../images/photo.jpg.
3. Write a complete, accessible image element
<img
src="images/product.webp"
alt="Blue ceramic mug on a wooden table"
width="1200"
height="800"
loading="lazy"
decoding="async"
>
src: the image URL requested by the browser.alt: a concise description. Usealt=""for purely decorative images.widthandheight: the intrinsic dimensions. They reserve space and reduce layout movement.loading="lazy": defers images below the initial viewport. Omit it for a prominent hero image that should load immediately.decoding="async": lets the browser decode without unnecessarily blocking other page work.
An <img> element is a void element, so it does not need a closing tag. It can use srcset and sizes when you have multiple resolutions:
<img
src="images/photo-800.jpg"
srcset="images/photo-400.jpg 400w,
images/photo-800.jpg 800w,
images/photo-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 800px"
alt="Mountain lake at sunrise"
width="1600"
height="1067"
>
4. Relative URLs versus absolute URLs
A relative URL such as images/photo.jpg follows the current document’s URL and is usually easiest to maintain when a site moves between domains or environments. An absolute URL includes the full origin:
<img src="https://cdn.example.com/images/photo.jpg" alt="...">
Use an absolute URL when the file is intentionally hosted on another domain or CDN. Confirm that the host permits cross-origin delivery and that the URL remains stable. Do not confuse either form with a local filesystem path such as C:\Users\Ada\Pictures\photo.jpg; a deployed browser cannot request that path from your computer.
5. Make images work in production
- Keep the image inside the directory copied or deployed with your HTML.
- Use URL separators (
/) in HTML, including on Windows. - Match spelling, capitalization, and extension exactly.
Photo.JPGandphoto.jpgcan be different files on Linux servers. - Encode spaces and special characters, or choose simple filenames such as
team-photo.webp. - Ensure your web server serves the image with an image content type such as
image/jpegorimage/png. - Keep public assets in the directory your framework exposes. For example, a framework may require files in a
publicdirectory and a root-relative URL such as/images/photo.jpg.
Relative paths are resolved against the document URL, including its directory. A page at /blog/post/ and one at /blog/post.html can therefore resolve the same-looking path differently. Inspect the final URL in the browser before choosing ./, ../, or a root-relative path.
6. Debug an image that does not appear
Check the requested URL
Open the image URL directly in a browser. From a page at https://example.com/pages/about.html, ../images/photo.jpg requests https://example.com/images/photo.jpg. Developer tools’ Network panel shows the exact request and status code.
| Symptom | Likely cause | Fix |
|---|---|---|
| 404 Not Found | Wrong directory, filename, extension, or deployment omission | Open the generated URL, count directory levels, and verify the deployed file exists. |
| Works locally, fails after deployment | Case-sensitive server or asset not copied | Match capitalization and inspect the production build output. |
| Broken image icon with a local file | Using a filesystem path or opening a page under an unexpected directory | Use a relative URL and serve the project through a local web server. |
| HTML loads but image is blocked | Content Security Policy, mixed content, hotlink protection, or authentication | Allow the image origin, use HTTPS, or serve the asset from your own site. |
| Image is distorted | Only one dimension was forced or the declared ratio is wrong | Preserve the intrinsic ratio; use CSS such as max-width:100%; height:auto. |
| Image is blank or corrupted | Invalid file, incomplete upload, or incorrect response content | Open the file directly, re-export it, and check the response headers. |
Use this checklist:
- Is the file actually inside the folder named in
src? - Does every character, capitalization, and extension match?
- Did you count upward directories correctly with
../? - Does the direct image URL return the file rather than an HTML error page?
- Did your build or hosting configuration publish the folder?
- Does the
alttext still communicate the meaning if loading fails?
7. Capture and verify the rendered result
When a page is generated by a build pipeline or needs visual checks, a screenshot can confirm that the deployed URL resolves the image. ScreenshotNeo provides website screenshots and PDFs from a URL, including full-page capture and custom waiting options. Its clean capture removes known cookie banners, newsletter popups, and chat widgets before the shot.
Or skip the browser setup
For a one-call capture of a page containing a folder image, use ScreenshotNeo’s API. See the ScreenshotNeo API documentation for request options.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com/page \
-o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com/page"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://example.com/page'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed; response headers identify the page verdict and whether it was billed. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
8. Performance, reliability, and cost notes
- Set
widthandheightto reduce layout shifts while the image downloads. - Use WebP or another suitable compressed format when your browser support requirements allow it.
- Use responsive
srcsetso mobile devices do not download oversized files. - Lazy-load below-the-fold images, but keep the main content image eager.
- Serve assets over HTTPS and let a CDN cache static files when traffic is distributed geographically.
- For automated screenshots, wait until the image and other page content are ready; ScreenshotNeo supports waiting for a selector, a delay, or network idle, plus caching with a chosen TTL.
FAQ
Should I start the path with a slash?
Use images/photo.jpg for a path relative to the current HTML file. A leading slash, /images/photo.jpg, starts at the site’s root and is appropriate only when that root location is intentional.
Can an image folder have another folder inside it?
Yes. Reference each directory in order, such as images/products/photo.jpg.
Why does ../images/photo.jpg work on one page but not another?
Each relative URL is resolved from the current document’s directory. Pages at different depths need different numbers of ../ segments.
Is alt required for the image to load?
No, but meaningful alt text is important for accessibility and provides useful fallback information when the image cannot be displayed.
Can I use an image hosted on a CDN?
Yes. Use its HTTPS URL, or configure your site and CDN so the asset is available at the relative or absolute URL in your markup.


