← Back to Rendering, JavaScript & Browser Diagnostics
Technical Growth Cookbook · Recipe 003

Hreflang alternate links: how to check if multilingual pages are connected correctly

A practical browser diagnostic for checking whether language versions of the same page are connected with clear, complete, and fully qualified hreflang alternate links.

JavaScript Technical SEO Hreflang International SEO

The business problem

When a website has different language or regional versions of the same page, search engines need a clear signal that those pages belong together. A visitor from Spain may need the Spanish page. A visitor from the Netherlands may need the Dutch page. A visitor using English may need the English page. The content may be similar, but the intended audience is different.

That is the role of hreflang. Hreflang is an HTML attribute used inside alternate link tags. It tells Google that a page has another version for a specific language or region.

<link rel="alternate" hreflang="es" href="https://matteoarellano.com/es/" />

The rel="alternate" part means “this is an alternate version of the current page.” The hreflang="es" part means “this alternate version is intended for Spanish-language users.” The href part gives the actual URL of that alternate page.

A practical example from my own website

My own website has three homepage language versions. The English version is:

https://matteoarellano.com/

The Spanish version is:

https://matteoarellano.com/es/

The Dutch version is:

https://matteoarellano.com/nl/

If these pages are intended to act as language alternatives of each other, each page should declare the full group. The English page should reference the English, Spanish, and Dutch versions. The Spanish page should also reference the English, Spanish, and Dutch versions. The Dutch page should do the same.

That means the Dutch page should not only point to the English and Spanish pages. It should also include itself:

<link rel="alternate" hreflang="en" href="https://matteoarellano.com/" />
<link rel="alternate" hreflang="es" href="https://matteoarellano.com/es/" />
<link rel="alternate" hreflang="nl" href="https://matteoarellano.com/nl/" />

This self-reference matters. If the current page is the Dutch page, the Dutch alternate set should include the Dutch page itself. In simple terms, the page is saying: “I am the Dutch version, and these are my English and Spanish siblings.”

Why self-reference matters

Google’s documentation explains that each language version should list itself as well as all other language versions. Google also says that if two pages do not point back to each other, the annotations may be ignored.

That is why hreflang is not just about adding a few tags. It is about creating a consistent relationship between equivalent pages. If the English page points to the Spanish page, the Spanish page should point back to the English page. If the Dutch page belongs to the same language cluster, it should also appear in that same group.

The business value is simple: when language versions are connected clearly, search engines have a better chance of showing the right page to the right audience.

When hreflang is actually necessary

Hreflang is not necessary for every website. If a website has only one language and no regional alternatives, missing hreflang is usually not a problem.

Hreflang becomes useful when the same or similar content exists for different users. This can happen when a website has English and Spanish versions, Dutch and English versions, Spanish pages for Spain and Mexico, or English pages for the US, UK, and Canada.

So the real question is not: “Does every page need hreflang?” The better question is: “Does this page have alternate language or regional versions for visitors?” If the answer is yes, hreflang helps Google understand the relationship between those pages.

What ISO language and region codes are

Hreflang values use standard language and region codes. A language code identifies the language. For example, en means English, es means Spanish, nl means Dutch, fr means French, and de means German.

A region code identifies the country or region. For example, US means United States, GB means United Kingdom, ES means Spain, MX means Mexico, and NL means Netherlands.

A hreflang value can be language-only:

es
nl
en

Or it can be language plus region:

es-ES
es-MX
en-US
en-GB
nl-NL

The first part is the language. The second part, if present, is the region. This distinction is important because a country code by itself is not enough. For example, GB is not a valid hreflang value because it is a region code, not a language code. A valid UK-focused English version would be en-GB.

Another common mistake is using informal regional labels, such as es-LATAM. This looks understandable to humans, but LATAM is not an ISO 3166-1 Alpha-2 region code.

The first DevTools snippet: list all hreflang links

You can quickly inspect a page’s hreflang tags in Chrome DevTools. Open the page, right-click, choose Inspect, go to the Console tab, and paste this:


const hreflangLinks = [
  ...document.querySelectorAll('link[rel~="alternate"][hreflang]')
];

console.log("Hreflang count:", hreflangLinks.length);

console.table(
  hreflangLinks.map((link, index) => ({
    index: index + 1,
    hreflang: link.getAttribute("hreflang"),
    hrefRaw: link.getAttribute("href"),
    hrefResolved: link.href,
    rel: link.getAttribute("rel"),
  }))
);

This shows each alternate link as a row. For a multilingual website, this is useful because you do not only want to know whether hreflang exists. You want to see the actual mapping between language and URL.

en -> https://matteoarellano.com/
es -> https://matteoarellano.com/es/
nl -> https://matteoarellano.com/nl/

The second DevTools snippet: check self-reference

The current page should appear inside its own hreflang set. This snippet normalizes the current URL, normalizes each hreflang URL, and checks whether the current page is included in the group.


function normalizeUrl(url) {
  const parsedUrl = new URL(url, window.location.href);

  parsedUrl.hash = "";

  if (parsedUrl.pathname.length > 1) {
    parsedUrl.pathname = parsedUrl.pathname.replace(/\/+$/, "");
  }

  return parsedUrl.toString();
}

const currentUrl = normalizeUrl(window.location.href);

const hreflangUrls = [
  ...document.querySelectorAll('link[rel~="alternate"][hreflang]')
].map((link) => normalizeUrl(link.href));

console.log("Current URL:", currentUrl);
console.log("Self-reference found:", hreflangUrls.includes(currentUrl));

If the result is Self-reference found: true, the current page references itself. If the result is Self-reference found: false, then either the page has no hreflang tags, or the hreflang set does not include the current page.

That distinction matters. If a page has no hreflang tags because it has no language alternatives, that may simply be “not applicable.” But if a page has many hreflang tags and still does not include itself, that is a real implementation issue.

The full checker: count, self-reference, x-default, and URL quality

This combined version gives you a more complete first check. It lists all hreflang links, checks whether the page references itself, checks whether an x-default fallback exists, and shows whether each URL was written as a fully qualified URL.


function normalizeUrl(url) {
  const parsedUrl = new URL(url, window.location.href);

  parsedUrl.hash = "";

  if (parsedUrl.pathname.length > 1) {
    parsedUrl.pathname = parsedUrl.pathname.replace(/\/+$/, "");
  }

  return parsedUrl.toString();
}

function hreflangAnalyzer() {
  const links = [
    ...document.querySelectorAll('link[rel~="alternate"][hreflang]')
  ];

  const currentUrl = normalizeUrl(window.location.href);

  const results = links.map((link, index) => {
    const hreflang = link.getAttribute("hreflang");
    const hrefRaw = link.getAttribute("href");
    const hrefResolved = link.href;
    const normalizedHref = normalizeUrl(hrefResolved);

    const isFullyQualified =
      hrefRaw && /^https?:\/\//i.test(hrefRaw);

    const isSelfReference = normalizedHref === currentUrl;

    return {
      index: index + 1,
      hreflang,
      hrefRaw,
      hrefResolved,
      isFullyQualified,
      isSelfReference,
      rel: link.getAttribute("rel"),
    };
  });

  const hasSelfReference = results.some((item) => item.isSelfReference);
  const hasXDefault = results.some(
    (item) =>
      item.hreflang && item.hreflang.toLowerCase() === "x-default"
  );

  console.log("Current URL:", currentUrl);
  console.log("Hreflang count:", links.length);
  console.log("Self-reference found:", hasSelfReference);
  console.log("x-default found:", hasXDefault);

  console.table(results);

  return {
    currentUrl,
    count: links.length,
    hasSelfReference,
    hasXDefault,
    results,
  };
}

hreflangAnalyzer();

Fully qualified URLs matter because hreflang annotations should point to clear, complete URLs such as https://matteoarellano.com/es/, not unclear relative paths such as /es/.

How SEO Page Audit 1.0.4 helps

I added hreflang checks to SEO Page Audit 1.0.4 to make this review faster. The extension checks whether hreflang tags are present on the current page, counts how many alternate links were found, checks whether the current page references itself, and checks whether an x-default fallback exists.

The extension can also show the actual alternate links line by line, so the user can see which language or region points to which URL. This is useful because a simple count is not enough. A page may have many hreflang tags, but the real question is whether those tags point to the right language versions, use valid codes, include self-reference, and form a consistent language cluster.

SEO Page Audit 1.0.4 also helps make invalid code checks more educational. Instead of only saying that something is wrong, it can show which part failed. For example, es-LATAM has a valid language component, es, but an invalid region component, LATAM.

View SEO Page Audit on the Chrome Web Store

The business value

Hreflang is a technical SEO signal, but the business problem is simple. If a company has pages for different countries or languages, it wants visitors to land on the most relevant version.

A Spanish-speaking visitor should not be sent to a Dutch page. A Dutch-speaking visitor should not be sent to a Spanish page. A user in Mexico may need different wording, pricing, contact options, or legal details than a user in Spain.

For developers, this is a quality assurance check. For marketers, it is an international SEO check. For business owners, it is a visibility and user experience check.

This is why browser diagnostics are valuable. A small JavaScript check can reveal whether a page is giving search engines a clear international targeting signal or whether the language versions are disconnected.

Quality checklist

  • The page has hreflang tags only when alternatives exist.
  • Each language version includes itself in the hreflang set.
  • Each language version lists all equivalent alternatives.
  • Each hreflang URL is fully qualified.
  • The language codes are valid ISO 639-1 codes.
  • The optional region codes are valid ISO 3166-1 Alpha-2 codes.
  • The page uses x-default when a fallback URL is useful.
  • The canonical URL and hreflang URL do not contradict the strategy.