ScreenshotNeo

BlogHow-to

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.

By the ScreenshotNeo team1 October 20268 min read

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:

  1. Start from the directory containing the HTML file, not from the project root you have open in your editor.
  2. Match every directory name and filename exactly.
  3. Check capitalization. Photo.jpg and photo.jpg can be different files on case-sensitive systems.
  4. Check the extension. A file named photo.webp is not addressed by photo.jpg.
  5. Escape spaces or, preferably, rename files with simple names such as hero-image.webp.
  6. 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 width and height to 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 alt for 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.