← Назад к вопросам

Как добавить ссылку, которая будет открываться в новом окне?

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

  1. Всегда используй rel="noopener noreferrer" для target="_blank"
  2. Указывай aria-label для доступности
  3. Добавляй иконку (↗) чтобы было видно что откроется новое окно
  4. Проверяй что URL безопасен перед открытием
  5. Для внешних ссылок используй target="_blank"
  6. Для внутренних ссылок используй Next.js Link (без target)

Это просто, но важно для безопасности и доступности приложения!

Как добавить ссылку, которая будет открываться в новом окне? | PrepBro