ScreenshotNeo

BlogHow-to

How to Link to Another Page in HTML

Learn how to create HTML links with relative paths, full URLs, fragments, new tabs, downloads, accessibility, and reliable troubleshooting.

By the ScreenshotNeo team1 October 20267 min read

Use an anchor element with an href attribute:

<a href="about.html">About this site</a>

The href value is the destination. The text between the opening and closing <a> tags is the visible, clickable label. When an a> element has href, HTML treats it as a hyperlink. See the HTML Living Standard and MDN’s anchor reference.

Suppose these files are in the same folder:

project/
├── index.html
└── about.html

Put this in index.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Home</title>
</head>
<body>
  <h1>Home</h1>
  <p>Learn <a href="about.html">about our organization</a>.</p>
</body>
</html>

Clicking the link asks the browser to resolve about.html relative to the folder containing index.html. The destination file must actually exist at that resolved path.

2. Choose the correct href path

Same directory

<a href="contact.html">Contact</a>

Child directory

If the destination is pages/contact.html below the current file:

<a href="pages/contact.html">Contact</a>

Parent directory

Use .. to move up one directory. If the current file is docs/start.html and the destination is index.html in the parent folder:

<a href="../index.html">Home</a>

Each additional .. moves up one level, but avoid paths that climb beyond the site root.

Root-relative paths

On a website, a path beginning with / starts at the domain root:

<a href="/pricing/">Pricing</a>

This is useful when many pages share a stable site structure. It behaves differently when opening files directly with a file:// URL, so test it through your local web server or deployed site.

External pages

Use the complete URL for another website:

<a href="https://developer.mozilla.org/">Read the MDN documentation</a>

Use https:// for secure external destinations. Verify the final URL and its spelling before publishing.

Give the destination element an id, then reference that ID after #:

<nav>
  <a href="#contact">Go to the contact section</a>
</nav>

<main>
  <h2 id="contact">Contact</h2>
  <p>Send us a message.</p>
</main>

The fragment is not sent to the server as a new page request; the browser uses it to scroll to the element whose id matches. IDs must be unique within the document and should not contain spaces.

You can combine a page URL and fragment:

<a href="guide.html#installation">Installation instructions</a>

Add target="_blank" when opening a new browsing context is part of the intended experience:

<a href="https://example.com" target="_blank" rel="noopener">
  Open the external reference in a new tab
</a>

Tell users that a new tab opens, either in the visible label or with an accessible explanation. MDN documents why unexpected new tabs can confuse users and recommends communicating the behavior.

rel="noopener" prevents the opened page from using the opener reference. Do not add target="_blank" to every link automatically; use it when preserving the current page is useful.

For a file hosted by your site, the download attribute requests a download:

<a href="files/guide.pdf" download>Download the HTML guide (PDF)</a>

You can suggest a filename:

<a href="files/guide.pdf" download="html-linking-guide.pdf">
  Download the guide (PDF)
</a>

Browser and server behavior can vary, especially for cross-origin URLs. Label the link with the file type and, when useful, its size.

Link text should make sense when read by itself. The W3C H30 technique recommends descriptive text, and MDN states that link content should indicate where the link goes even out of context.

<!-- Good -->
<a href="pricing.html">View pricing plans</a>

<!-- Weak -->
<a href="pricing.html">Click here</a>

For repeated links, include enough surrounding context to distinguish them. If a link opens a new tab or downloads a file, say so in the label or an accessible adjacent description.

An anchor represents navigation. A button represents an action on the current page, such as opening a dialog, toggling a panel, or submitting a form.

<!-- Navigation -->
<a href="settings.html">Open settings</a>

<!-- Action -->
<button type="button" id="save-button">Save changes</button>

Avoid href="#" and href="javascript:void(0)" as fake buttons. MDN notes that these patterns can interfere with copying, dragging, opening in a new tab, bookmarking, keyboard use, and behavior when JavaScript is unavailable.

8. Common errors and fixes

Symptom Likely cause Fix
404 Not Found The path or filename does not match the deployed file. Check spelling, capitalization, extension, and the path relative to the current document.
Link works locally but fails after deployment The host uses case-sensitive paths or a different directory structure. Match URL case exactly and inspect the deployed folder tree.
Browser opens the wrong page A relative path was calculated from the current page, not the project root. Count directory levels and use ../ or a root-relative path as appropriate.
Fragment does not scroll No element has the matching id, or the ID is duplicated. Use one exact, case-sensitive ID and reference it as #that-id.
Download opens in the browser The server or browser controls treatment of the resource, especially cross-origin files. Serve the file from your site when possible and keep the download label explicit.
New-tab link surprises users target="_blank" is not communicated. Say “opens in a new tab” and include rel="noopener".
Click does nothing The element is not a real anchor, JavaScript cancels the event, or CSS overlays it. Use <a href="...">, inspect event handlers, and check layout in developer tools.

9. A complete multi-page example

This small example links home, an internal page, an external reference, a same-page section, and a download:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Example links</title>
</head>
<body>
  <nav aria-label="Primary navigation">
    <a href="index.html">Home</a>
    <a href="about.html">About this site</a>
    <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a"
       target="_blank" rel="noopener">
      Read the MDN anchor reference (opens in a new tab)
    </a>
  </nav>

  <p><a href="#resources">Jump to resources</a></p>

  <section id="resources">
    <h2>Resources</h2>
    <a href="files/guide.pdf" download="html-guide.pdf">
      Download the HTML guide (PDF)
    </a>
  </section>
</body>
</html>

10. Performance and reliability checklist

  • Use stable, readable URLs and keep internal paths consistent.
  • Prefer descriptive labels so users and assistive technology can understand destinations quickly.
  • Check internal links after moving or renaming files.
  • Use HTTPS for external destinations.
  • Test links with keyboard navigation and with JavaScript disabled when navigation should still work.
  • Check deployed URLs on a case-sensitive server.
  • Use redirects when an old public URL must continue working after a move.

HTML links have no per-click API cost. The operational risks are broken paths, unexpected navigation, inaccessible labels, and destination availability. A link itself cannot guarantee that the target site remains online.

11. Or skip the browser setup

If your next step is generating screenshots of linked pages, ScreenshotNeo can capture a URL with one request. Its cleanup steps accept cookie and consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. See the ScreenshotNeo API documentation.

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

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));

ScreenshotNeo also provides an MCP server for Claude, Cursor, and other MCP clients, with take_screenshot, get_page_info, and capture_pdf tools. One thousand screenshots per month are free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

12. FAQ

Should I use a relative URL or an absolute URL?

Use a relative path for nearby pages in the same site structure. Use a full URL for an external site. Root-relative paths beginning with / are useful on deployed sites with a stable domain root.

Yes. Include the folder path, such as docs/guide.html, or move upward with ../ when the destination is in a parent directory.

Add a unique id to the destination element and link to #id-value.

When should I use a button instead?

Use a button for an action that does not navigate to a URL. Use an anchor for navigation.

No. A normal anchor with a valid href works without JavaScript.