Read the actual hostname in an unfamiliar link
Read the hostname as a parsed URL field rather than guessing from the first familiar word in the address. In https://[email protected]:8443/a, the hostname is shop.example.test; the earlier text is user information and 8443 is the port.
Separate the address into fields
An address combines several kinds of information. The scheme says how the address is interpreted, the hostname identifies the named host, and the path identifies a resource within the address.1 A query and fragment can add further text. Those fields can contain familiar words without changing the hostname.
Keep the original string available while reading the parsed result. Normalization can change its appearance, including case, a default port or an internationalized hostname.2 Comparing the two helps you notice which part of your impression came from typography and which part came from the parser’s structure.
This example accepts an absolute HTTP or HTTPS URL and prints five fields. It deliberately does not add a missing scheme or supply a base address. If the input is only /account, there is no declared website against which to resolve it. Returning an explanation is more useful here than silently assuming one.
The hostname is not an ownership certificate. It is the field you need before asking who controls the address or whether it matches the service you intended. Those later questions need evidence beyond this component.
A complete hostname reader
Save this original MIT example as an HTML page. The input stays inside the page; the button creates a URL object and writes its fields into a text container. There is no destination navigation or network request in the component’s code.
<!doctype html>
<!-- SPDX-License-Identifier: MIT -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Read the parsed hostname</title>
<style>
body { font: 1rem/1.5 system-ui; margin: 2rem; max-width: 44rem; }
label, textarea, select { display: block; margin-block: .75rem; }
textarea { width: 100%; min-height: 5rem; }
button { padding: .5rem 1rem; margin: .5rem .5rem .5rem 0; }
pre { white-space: pre-wrap; overflow-wrap: anywhere; }
:focus-visible { outline: 3px solid #16624c; outline-offset: 3px; }
</style>
</head>
<body>
<h1>Read the parsed hostname</h1>
<p>This example reads text. It does not open the destination or judge it.</p>
<label for="address">Absolute HTTP or HTTPS URL</label>
<textarea id="address" spellcheck="false" autocomplete="off">https://[email protected]:8443/a</textarea>
<button id="inspect" type="button">Read hostname</button>
<button id="clear" type="button">Clear</button>
<p id="message" role="status"></p>
<pre id="fields" aria-label="Parsed fields"></pre>
<script>
const address = document.querySelector("#address");
const fields = document.querySelector("#fields");
const message = document.querySelector("#message");
function inspect() {
fields.textContent = "";
try {
const parsed = new URL(address.value);
if (!["http:", "https:"].includes(parsed.protocol)) {
throw new Error("Use an absolute HTTP or HTTPS URL.");
}
const userinfo = parsed.username || parsed.password;
fields.textContent = [
"Scheme: " + parsed.protocol,
"Hostname: " + parsed.hostname,
"Port: " + (parsed.port || "not retained / scheme default"),
"User information: " + (userinfo ? "present" : "absent"),
"Path: " + parsed.pathname
].join("\n");
message.textContent = "Parsed as text. This is not a reputation check.";
} catch {
message.textContent = "Enter an absolute HTTP or HTTPS URL; no base is guessed.";
}
}
document.querySelector("#inspect").addEventListener("click", inspect);
document.querySelector("#clear").addEventListener("click", () => {
address.value = "";
fields.textContent = "";
message.textContent = "Input and result cleared.";
address.focus();
});
inspect();
</script>
</body>
</html>
Case one: a familiar word before the at sign
The initial example puts trusted.example.test in the user-information position. The hostname output is still shop.example.test. The display reports that user information is present without repeating its contents, because a password or other sensitive string could occupy that field in a different input.
Read the hostname output in the demo before comparing it with the text you expected. This is a reading exercise using reserved names, not an invitation to visit an address. The port is separate, so it cannot hide at the end of the hostname output.
The same approach helps with a long subdomain. In accounts.department.example.test, all four labels belong to the hostname. Identifying the registrable boundary requires a suffix rule; simply keeping the last two labels is not a general solution.3 The boundary reference covers that next step.
Case two: Unicode and ASCII display
An internationalized hostname may have an ASCII form beginning with xn--. In the printed example, bücher.example.test is displayed as xn--bcher-kva.example.test by the browser’s hostname property.4 The output is a representation of the parsed name, not a translation or a claim about who registered it.
Legitimate names use non-ASCII characters. A reader should not turn the presence of punycode into a verdict. Conversely, a name that looks familiar in one font may contain different characters. The full URL inspector shows both forms and limited structural flags so the two views can be compared.
The small reader intentionally avoids a homemade visual-trust score. It would be misleading to classify every language it does not recognize as suspicious, or to imply that a short list of lookalikes catches every impersonation. Unicode’s security guidance describes a broader problem5 than this teaching component attempts to solve.
Case three: a path that looks like another address
Consider https://shop.example.test/help/trusted.example.test. The last portion is a path. A string resembling a host inside that path does not become the hostname of this URL. The reader prints the path on its own line so you can keep those roles separate.
A query can also contain another address, for example as a return destination. This component does not follow it or decide how an application would use it. Reading a nested value can be useful, but only after recognizing that it is data within the outer URL. Application behavior could differ from the visible string and needs its own evidence.
Do not decode and rebuild the entire address merely to make it easier to read. Changing separators or encoded text can change the string being assessed. Preserve the original and treat each representation as a separate view of it.
Case four: rejected input and clearing the page
The new URL call has no base argument. A relative path therefore produces the explanatory message instead of a guessed hostname. A parsed non-HTTP scheme also receives that message because this particular reader is limited to web addresses. That limit belongs to the example’s scope; it is not a claim that other schemes are invalid everywhere.
Before parsing, the code clears the previous output. An error therefore cannot leave an old hostname on the screen beneath a new input. Clear removes both input and output, updates the status text and returns keyboard focus to the input. It does not operate on clipboard history or another application’s copy of the address.
textContent makes the output literal text.6 The code never assigns a pasted string to an anchor’s href or inserts it as HTML. That distinction matters when a value contains characters that resemble markup: the reader’s job is to display a representation, not interpret a new document from it.
Use the result for the next decision
Compare the extracted hostname with a destination you already know through an independent route. If an unsolicited message claims to come from an organisation, its own link text is not independent confirmation of that claim. You can stop without opening the link; a structural explanation does not oblige you to continue.
If a password-reset or invitation token appears elsewhere in the address, keep that full string out of public reports. The submission-privacy guide explains why sharing only a hostname changes the evidence and may still disclose a private tenant name. If a browser warning is already present, this parsing exercise does not override it.
Not covered on this page
- Ownership, registration records or live DNS.
- Redirect destinations or the contents of a page.
- Reputation verdicts or instructions to bypass a warning.
- Complete Unicode spoof detection.
Sources
-
RFC 3986: URI generic syntax. Opened 24 October 2026. ↩
-
URL interface. Opened 24 October 2026. ↩
-
Public Suffix List: learn more. Opened 24 October 2026. ↩
-
URL.hostname. Opened 24 October 2026. ↩
-
Unicode security mechanisms, UTS #39. Opened 24 October 2026. ↩
-
Node.textContent. Opened 24 October 2026. ↩
How we test: methodology. Found a mistake? Corrections.