How to Load a Local Image Into an HTML Page
Learn the correct HTML image paths, accessible alt text, local previews, troubleshooting, and how to verify a page screenshot.
To load an image that belongs to your website, put the image inside the project and reference it with an <img> element. Set src to the image path relative to the HTML document and provide useful alt text.
<img src="photo.jpg" alt="A description of the photo">
The example works when photo.jpg is beside the HTML file. If the image is in a folder, include that folder in the path:
<img src="images/photo.jpg" alt="A description of the photo">
Relative paths are resolved from the document’s base URL. A <base> element can change that base, so check for one if a path behaves unexpectedly. See the MDN guide to HTML images and the img element reference.
1. Put the image in your project
A simple project might look like this:
project/
index.html
images/
photo.jpg
Because index.html is one level above images, its markup is:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Local image example</title>
</head>
<body>
<h1>Product photo</h1>
<img
src="images/photo.jpg"
alt="A blue ceramic mug on a wooden table"
width="1200"
height="800"
>
</body>
</html>
Same-folder image
project/
index.html
photo.jpg
<img src="photo.jpg" alt="A blue ceramic mug on a wooden table">
Nested folders
For this layout, the path starts at the location of the HTML file:
project/
pages/
about.html
assets/
team.jpg
<img src="../assets/team.jpg" alt="The product team standing together">
.. moves up one directory. Two parent directories require ../../. Avoid starting a project-relative path with a slash unless you intentionally mean the website root, because /images/photo.jpg is different from images/photo.jpg.
2. Write the image element correctly
| Attribute | Purpose | Example |
|---|---|---|
src |
Image URL or relative path | images/photo.jpg |
alt |
Accessible alternative text | alt="Blue mug" |
width |
Intrinsic width in CSS pixels | width="1200" |
height |
Intrinsic height in CSS pixels | height="800" |
loading |
Optional loading hint | loading="lazy" |
Choose useful alt text
- Describe the content or purpose, not the filename:
alt="Blue ceramic mug on a wooden table". - For an image that is purely decorative, use empty alternative text:
alt="". - Do not repeat nearby text. If a heading already says “Pricing,” a decorative image may need
alt="". - Do not omit
alt; omission can cause assistive technology to announce the filename or path.
Reserve layout space
When the dimensions are known, include width and height. The browser can reserve the correct aspect ratio before the file arrives, reducing layout shifts.
<img
src="images/landscape.jpg"
alt="Mountain landscape at sunrise"
width="1600"
height="900"
>
The attributes do not need to match the rendered size. Use CSS for responsive display:
img {
max-width: 100%;
height: auto;
display: block;
}
3. Understand paths, filenames, and the document base
Most missing-image errors come from a path that does not match the actual project. Check all of these details:
- Start from the directory containing the HTML file, not from the project root you have open in your editor.
- Match every directory name and filename exactly.
- Check capitalization.
Photo.jpgandphoto.jpgcan be different files on case-sensitive systems. - Check the extension. A file named
photo.webpis not addressed byphoto.jpg. - Escape spaces or, preferably, rename files with simple names such as
hero-image.webp. - Look for a
<base href="...">element, which changes how relative URLs are resolved.
These paths are different:
<!-- Same folder as the HTML file -->
<img src="photo.jpg" alt="...">
<!-- Child folder -->
<img src="images/photo.jpg" alt="...">
<!-- Parent folder, then child folder -->
<img src="../images/photo.jpg" alt="...">
<!-- Website root; not the same as images/photo.jpg -->
<img src="/images/photo.jpg" alt="...">
4. Load an image selected by a visitor
A project asset and a file chosen from a visitor’s computer are separate cases. A page cannot guess an arbitrary local path on the visitor’s device. Use a file input and read the selected File with JavaScript.
<label for="image-file">Choose an image</label>
<input id="image-file" type="file" accept="image/*">
<img id="preview" alt="Selected image preview" hidden>
<script>
const input = document.querySelector('#image-file');
const preview = document.querySelector('#preview');
let objectUrl;
input.addEventListener('change', () => {
const file = input.files[0];
if (!file) {
preview.hidden = true;
return;
}
if (!file.type.startsWith('image/')) {
input.value = '';
preview.hidden = true;
return;
}
if (objectUrl) URL.revokeObjectURL(objectUrl);
objectUrl = URL.createObjectURL(file);
preview.src = objectUrl;
preview.alt = `Preview of ${file.name}`;
preview.hidden = false;
});
</script>
URL.createObjectURL(file) creates a temporary object URL for the selected file. Revoke the previous URL when replacing it, and revoke the final URL when a longer-lived application no longer needs it. The browser intentionally hides the real local path and scripts cannot set a file input to an arbitrary path.
5. Test a local HTML page reliably
Opening a file directly produces a file:// URL. Relative paths can work there, but local-file access and security behavior vary between browsers and operating systems. A small local server gives you normal HTTP URL resolution and makes developer-tool diagnosis easier.
Python built-in server
cd project
python3 -m http.server 8000
Open http://localhost:8000/, then inspect the image request in your browser’s Network panel.
Node.js server option
npx serve project
Use the URL printed by the command. Keep the terminal running while you refresh the page.
6. Troubleshoot a missing or broken image
| Symptom | Likely cause | Fix |
|---|---|---|
| Broken-image icon | Wrong relative path | Calculate the path from the HTML file’s directory and inspect the failed request. |
| Works on one computer only | Filename capitalization differs | Rename the file and reference the exact case. |
| 404 in Network tools | File is outside the served directory or extension is wrong | Move the asset under the server root or correct src. |
| Image appears after layout jumps | No intrinsic dimensions | Add accurate width and height, then use responsive CSS. |
| Image is stretched | CSS forces both dimensions | Set height: auto or preserve the source aspect ratio. |
| Preview does not update | No file selected or stale object URL | Read input.files[0], handle cancel, and replace the object URL. |
Works via HTTP but not file:// |
Browser local-file security behavior | Use a local development server. |
| Only some images fail | Unsupported or mislabeled format | Confirm the file opens, check its MIME type, and use a browser-supported format. |
In DevTools, check the Console and Network tabs. A 404 identifies a path problem; a successful response with a broken display points toward a file format, decoding, or CSS issue. A response blocked by policy may require checking server headers or the page’s security configuration.
7. Performance and reliability checklist
- Use an appropriately sized image and modern formats such as WebP or AVIF when your browser support requirements allow them.
- Set
widthandheightto reserve space. - Use
loading="lazy"for below-the-fold images, but avoid lazy loading the main above-the-fold image. - Keep stable, simple filenames and review paths after moving files.
- Serve assets over HTTP in development and production so failures appear as inspectable requests.
- Use meaningful alternative text and empty
altfor decorative images. - For user-selected files, validate the file type and size before previewing or uploading.
Or skip the browser setup
If your goal is to obtain a screenshot of a finished, reachable page rather than implement the HTML image itself, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one GET request. Its cleanup steps accept cookie banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off.
Only clean shots are billed. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response reports the result with X-Page-Verdict and X-Billed headers. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
See the ScreenshotNeo API documentation for all options. The basic request is:
cURL
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com \
-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"},
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'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', data));
ScreenshotNeo includes full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets, custom viewports, retina scale, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, caching with a chosen TTL, signed links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work for easier migration.
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account to get started.
FAQ
Can HTML load an image from my computer with an absolute local path?
A deployed page cannot use your computer’s private path. Put a project asset in the site or let the visitor select a file with an input type="file".
Should I use a relative URL or an absolute URL?
Use a relative URL for an image shipped with the same site. Use an absolute HTTPS URL only when the image is hosted elsewhere and that host permits access.
Why does ../ appear in image paths?
Each .. moves up one directory from the HTML document’s location.
Do I need JavaScript for a normal project image?
No. A known project asset needs only <img src="..." alt="...">. JavaScript is needed for interactions such as previewing a visitor-selected file.
What should I check first when an image is invisible?
Inspect the request in DevTools, confirm the path and capitalization, and verify that CSS is not hiding or covering the image.


