Chcete, aby se vám odkazy, které vedou mimo web, otevíraly do nového okna? Pak vám stačí kousek JS, který vložíte do patičky a máte vystaráno.
Jednoduchá varianta
<script>
document.addEventListener('DOMContentLoaded', function () {
const currentDomain = window.location.hostname;
document.querySelectorAll('a[href]').forEach(function (link) {
const href = link.getAttribute('href');
// ignoruj kotvy, javascript a mailto
if (
!href ||
href.startsWith('#') ||
href.startsWith('javascript:') ||
href.startsWith('mailto:')
) {
return;
}
try {
const url = new URL(href, window.location.origin);
if (url.hostname !== currentDomain) {
link.setAttribute('target', '_blank');
link.setAttribute('rel', 'noopener noreferrer');
}
} catch (e) {
// nevalidní URL – ignorujeme
}
});
});
</script>
Vytuněná varianta
Pokud chcete vytuněnější variantu i s “konfigurací”, bude pro vás to pravé skript níže:
- ignoruje url jako odkaz na email, telefon nebo kotvy,
- můžete si nastavit, jestli má target změny vždy nebo jen někdy,
- nastavit
relhodnoty, - pořád to platí jen pro odkazy, které jdou mimo domen.
<script>
document.addEventListener('DOMContentLoaded', function () {
// ── Config ──────────────────────────────────────────────
const config = {
// 'ifMissing' – nastaví _blank jen pokud atribut chybí
// 'overwrite' – vždy přepíše
// 'keep' – nikdy nesahá na atribut
targetMode: 'ifMissing',
// 'ifMissing' – nastaví jen pokud atribut chybí
// 'overwrite' – vždy přepíše celý rel
// 'keep' – nikdy nesahá na atribut
// 'merge' – přidá chybějící hodnoty, zachová stávající
relMode: 'merge',
// hodnoty, které skript přidává/nastavuje
targetValue: '_blank',
relValues: ['noopener', 'noreferrer'],
};
// ─────────────────────────────────────────────────────────────
const currentDomain = window.location.hostname;
document.querySelectorAll('a[href]').forEach(function (link) {
const href = link.getAttribute('href');
// ignore anchors kotvy, javascript, mailto, tel, sms
if (
!href ||
href.startsWith('#') ||
href.startsWith('javascript:') ||
href.startsWith('mailto:') ||
href.startsWith('tel:') ||
href.startsWith('sms:')
) {
return;
}
try {
const url = new URL(href, window.location.origin);
if (url.hostname !== currentDomain) {
// ── target ──────────────────────────────────────────
const hasTarget = link.hasAttribute('target');
if (
config.targetMode === 'overwrite' ||
(config.targetMode === 'ifMissing' && !hasTarget)
) {
link.setAttribute('target', config.targetValue);
}
// 'keep' → do not touch
// ── rel ─────────────────────────────────────────────
const hasRel = link.hasAttribute('rel');
if (config.relMode === 'keep') {
// do not touch
} else if (config.relMode === 'overwrite') {
link.setAttribute('rel', config.relValues.join(' '));
} else if (config.relMode === 'ifMissing' && !hasRel) {
link.setAttribute('rel', config.relValues.join(' '));
} else if (config.relMode === 'merge') {
const existing = hasRel
? link.getAttribute('rel').split(/\s+/).filter(Boolean)
: [];
const merged = [...new Set([...existing, ...config.relValues])];
link.setAttribute('rel', merged.join(' '));
}
}
} catch (e) {
// invalid URL - ignore
}
});
});
</script>

