Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

To display an image from a URL, put that URL in an HTML <img> element’s src attribute. Use JavaScript fetch() instead only when you need to read or process the image bytes; for a different origin, that request requires the image server’s CORS permission.

Display an image with an HTML <img> element

For ordinary display, the browser can request the image directly as a page resource. Use an absolute URL when the image is hosted elsewhere or a path relative to the page when it is part of your site:

<img src="https://example.com/photo.jpg" alt="A red bicycle leaning against a wall" width="800" height="600">

Replace the sample URL and description with the image you intend to show. The browser fetches the resource and renders it where the element appears. The alt text should convey the image’s relevant meaning; if the image is purely decorative and adds no information, use alt="".

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Absolute and relative image URLs

An absolute URL identifies the image’s full address, including its scheme and host, such as https://example.com/photo.jpg. A relative URL is resolved from the address of the current document. For example, images/photo.jpg refers to an images folder relative to the page’s location. If the browser requests a different file than you expected, check the resolved address in the browser’s developer tools.

Reserve space with dimensions

When the image’s dimensions are known, add its width and height attributes. These give the browser the image’s proportions before it finishes loading, reserving layout space and helping avoid content shifting when the image appears. Use the image’s real dimensions or equivalent proportions; values that do not match its shape can distort the display.

Choose responsive sources and loading behavior

A single src is enough when one image file is suitable at every display size. If you have alternate sizes, srcset offers candidates and sizes describes how much layout space the image is expected to occupy. The browser can then choose a suitable source:

<img src="small.jpg"
     srcset="small.jpg 480w, large.jpg 1200w"
     sizes="(max-width: 600px) 100vw, 800px"
     alt="Description of the image"
     width="800" height="600">

In this example, the source candidates are associated with their widths, while sizes describes a layout that uses the full viewport up to 600 pixels and 800 pixels of space above that breakpoint. Keep src as a fallback candidate. These attributes help with responsive delivery; they do not grant permission to read image bytes from another origin.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For an image well below the visible part of the page, loading="lazy" can defer its request until it is needed:

<img src="https://example.com/article-image.jpg"
     alt="A detail from the article"
     width="800" height="600"
     loading="lazy">

Do not lazy-load a key hero image that should be available immediately. Use lazy loading selectively for below-the-fold content. Dimensions and loading behavior address layout and timing, not whether a remote server permits JavaScript access.

Use JavaScript when you need the image data

If you only want an image to appear, use <img src>. Use fetch() when your code must inspect, transform, authenticate, or otherwise handle the HTTP response before displaying it. For an image hosted on another origin, the server must allow your page’s origin through CORS. A runnable example is:

async function loadImage(url, img) {
  const response = await fetch(url); // Cross-origin requests require CORS permission.
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const blob = await response.blob();
  const objectURL = URL.createObjectURL(blob);

  img.onload = () => URL.revokeObjectURL(objectURL);
  img.onerror = () => URL.revokeObjectURL(objectURL);
  img.src = objectURL;
}

loadImage(
  "https://example.com/photo.jpg",
  document.querySelector("#preview")
);

The page needs a target element, for example <img id="preview" alt="Preview of the selected photo">. The code checks the HTTP status, reads the response as a Blob, creates a temporary object URL for that Blob, and assigns it to the image. Revoke the object URL after loading (and on an image error) when it is no longer needed, so the page does not retain unnecessary browser memory.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why a URL that works in an image may fail in fetch

A browser can display a remote resource through an ordinary image element without giving page JavaScript permission to read the response. Fetching the image is a different operation: for a cross-origin request, the remote server must return an Access-Control-Allow-Origin header that allows the requesting page. If it does not, JavaScript cannot read the response, even if the same address displays in <img src>.

Setting mode: "no-cors" does not bypass this restriction. It gives JavaScript an opaque response whose contents cannot be read, so it does not help when the code needs the image bytes. If you control the image server, configure its CORS response for the origin that needs access. If you do not, a server-side proxy under your control may fetch and re-serve the image; protect that proxy with authentication, caching, size limits, and content-rights controls.

Load a remote image into a canvas

Canvas has an additional security concern: drawing a cross-origin image without appropriate CORS permission taints the canvas. The drawing may appear, but pixel-reading or export operations such as toDataURL() and toBlob() will fail. Set crossorigin="anonymous" on the image before assigning its remote src, and make sure the image server sends a compatible CORS header:

<img id="source" crossorigin="anonymous" alt="Source image">
<canvas id="canvas"></canvas>
<script>
  const source = document.querySelector('#source');
  source.crossOrigin = 'anonymous';
  source.src = 'https://cdn.example.com/photo.jpg';

  source.onload = () => {
    const canvas = document.querySelector('#canvas');
    canvas.getContext('2d').drawImage(source, 0, 0);
    // Pixel reading or export also requires the server's CORS permission.
  };
</script>

The order matters: configure the CORS mode before the browser starts loading the image. The client-side attribute or property requests CORS-enabled loading; it does not create permission by itself. The remote image server must still allow the page’s origin. If it does not, use an image source you control or a carefully secured server-side proxy rather than expecting canvas export to work.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is to capture a webpage as an image or PDF rather than embed an existing image file in HTML, ScreenshotNeo provides a screenshot API and MCP server. That is a different task from displaying an image URL with <img>; it can return a clean screenshot of the page at the URL. Here is a one-request cURL example:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify the page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. See ScreenshotNeo for the service and sign up for free.

Troubleshoot an image that does not appear

  • Check the requested address. Confirm that the URL points to the intended image and is reachable over HTTPS. For a relative path, check the resolved URL rather than assuming it is relative to the site root.
  • Inspect the Network panel. In your browser’s developer tools, check the request status, redirects, response MIME type, and whether the request was blocked. These details help distinguish a missing resource or redirect from a browser policy issue.
  • If only fetch fails, check CORS. If the image works in an <img> but the fetch request cannot read it, inspect the response’s Access-Control-Allow-Origin header. The image server needs to permit the requesting origin.
  • If canvas export fails, check both sides. Set crossorigin="anonymous" before src, then verify that the image server sends a compatible CORS header. Without both, the canvas may be tainted.
  • Check your Content Security Policy. A page’s img-src policy can block an otherwise valid image URL. Allow the relevant image source in the policy if it is appropriate for your site.
  • Release temporary object URLs. When displaying a Blob created by URL.createObjectURL(), revoke the URL after the image loads or errors if you no longer need it.

Choose the right approach

  • Just show the image: use <img src="…" alt="…">. Cross-origin byte access is not needed for ordinary display.
  • Read, transform, or authenticate the response in browser JavaScript: use fetch() and handle the response as a Blob, but make sure a cross-origin server permits the request through CORS.
  • Read pixels or export a canvas: configure CORS on the image element before setting its source and get matching permission from the image server.
  • Improve delivery and layout: use responsive candidates with srcset and sizes, defer below-the-fold images with lazy loading, and provide dimensions when known. These choices do not change CORS access.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.