← Назад к вопросам
Как добавить ссылку, которая будет открываться в новом окне?
1.3 Junior🔥 151 комментариев
#HTML и CSS
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Открытие ссылок в новом окне
Это простой, но важный вопрос о правильном использовании HTML и security.
Базовый способ: target="_blank"
<!-- Самый простой вариант -->
<a href="https://example.com" target="_blank">Open in new window</a>
<!-- С указанием что это внешняя ссылка (доступность) -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer">
Open in new window
<span aria-label="(opens in new window)"></span>
</a>
Важность rel="noopener noreferrer"
<!-- ОПАСНО: без rel -->
<a href="https://example.com" target="_blank">Link</a>
<!-- Почему опасно?
Новая страница имеет доступ к window.opener
может перенаправить исходную страницу на фишинг сайт!
Вредный код на example.com:
window.opener.location = 'https://phishing-site.com';
Пользователь вернётся на фишинг сайт вместо оригинального!
-->
<!-- ПРАВИЛЬНО: с rel -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer">Link</a>
<!-- Что делают флаги:
noopener = новое окно НЕ имеет доступ к window.opener
referrer = не отправляем referrer (откуда пришли)
-->
В React компоненте
// Функциональный компонент с типизацией
interface ExternalLinkProps {
href: string;
children: React.ReactNode;
className?: string;
}
export function ExternalLink({
href,
children,
className
}: ExternalLinkProps) {
return (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className={className}
aria-label={`${children} (opens in new window)`}
>
{children}
<span className="ml-1" aria-hidden="true">↗</span>
</a>
);
}
// Использование
<ExternalLink href="https://example.com">
Посетить пример
</ExternalLink>
Встроенная функция JavaScript
Если нужна больше контроля:
// Функция для безопасного открытия
function openInNewWindow(url: string) {
const newWindow = window.open(url, '_blank');
if (newWindow) {
// Удалить доступ к window.opener
newWindow.opener = null;
// Или просто
newWindow?.focus();
}
}
// Использование
<button onClick={() => openInNewWindow('https://example.com')}>
Open Link
</button>
Проверка внутренних и внешних ссылок
interface LinkProps {
href: string;
children: React.ReactNode;
}
export function Link({ href, children }: LinkProps) {
const isExternal = href.startsWith('http') || href.startsWith('//');
if (isExternal) {
// Внешняя ссылка
return (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
>
{children}
</a>
);
} else {
// Внутренняя ссылка (Next.js Link)
return (
<NextLink href={href}>
{children}
</NextLink>
);
}
}
Правильная разметка для доступности
<!-- Плохо: не понятно что окно откроется -->
<a href="https://example.com" target="_blank">Learn more</a>
<!-- Хорошо: явно указано для экранных считывателей -->
<a
href="https://example.com"
target="_blank"
rel="noopener noreferrer"
aria-label="Learn more (opens in new window)"
>
Learn more
<svg className="w-4 h-4 ml-1" aria-hidden="true">
<use href="#icon-external-link" />
</svg>
</a>
Различные варианты rel
<!-- noopener: новое окно НЕ имеет доступ к window.opener -->
<a href="..." target="_blank" rel="noopener">
<!-- noreferrer: не отправляем информацию об источнике трафика -->
<a href="..." target="_blank" rel="noreferrer">
<!-- noopener + noreferrer: оба флага -->
<a href="..." target="_blank" rel="noopener noreferrer">
<!-- external: явно указываем что это внешняя ссылка -->
<a href="..." rel="external">
<!-- ugc: User-Generated Content (форумы, комментарии) -->
<a href="..." rel="ugc">
Кейсы использования
Кейс 1: Ссылка в подвале (внешняя)
export function Footer() {
return (
<footer>
<a
href="https://privacy.example.com"
target="_blank"
rel="noopener noreferrer"
>
Privacy Policy
</a>
</footer>
);
}
Кейс 2: Ссылка в статье
export function Article({ content }) {
return (
<article>
<h1>{content.title}</h1>
<p>{content.body}</p>
<p>
Читай больше на{' '}
<a
href={content.sourceUrl}
target="_blank"
rel="noopener noreferrer"
>
источнике
</a>
</p>
</article>
);
}
Кейс 3: Кнопка для открытия
export function ShareButton() {
const handleShare = () => {
window.open(
`https://twitter.com/intent/tweet?url=${window.location.href}`,
'_blank',
'width=550,height=420'
);
};
return <button onClick={handleShare}>Share on Twitter</button>;
}
Best practices
- Всегда используй rel="noopener noreferrer" для target="_blank"
- Указывай aria-label для доступности
- Добавляй иконку (↗) чтобы было видно что откроется новое окно
- Проверяй что URL безопасен перед открытием
- Для внешних ссылок используй target="_blank"
- Для внутренних ссылок используй Next.js Link (без target)
Это просто, но важно для безопасности и доступности приложения!