Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Скрипты в компонентах

Не каждой кнопке нужен React. Для простого поведения — открыть меню, скопировать ссылку, переключить тему — хватит обычного JavaScript в теге <script> внутри компонента .astro. Astro обработает такой скрипт при сборке и подключит его к странице.

Кнопка «Скопировать ссылку»

Создайте src/components/CopyLink.astro:

<button class="copy-link">Скопировать ссылку</button>
 
<script>
  const buttons = document.querySelectorAll('.copy-link');
 
  buttons.forEach((button) => {
    button.addEventListener('click', async () => {
      await navigator.clipboard.writeText(location.href);
      button.textContent = 'Скопировано';
    });
  });
</script>

Вставьте <CopyLink /> в страницу статьи src/pages/posts/[id].astro после <Content />. Откройте статью и нажмите кнопку: адрес страницы окажется в буфере обмена, а надпись сменится на «Скопировано».

Что делает Astro со скриптом

ОсобенностьЧто это значит
МодульСкрипт работает как type="module": можно писать import
TypeScriptВнутри можно писать на TypeScript
Один разЕсли компонент стоит на странице трижды, скрипт подключится один раз
СборкаКод собирается и сжимается в отдельный файл

Из-за «одного раза» скрипт ищет все кнопки через querySelectorAll, а не одну: так он обслужит каждый экземпляр компонента.

Данные из фронтматтера

Скрипт выполняется в браузере и не видит переменных фронтматтера. Данные передают через атрибуты data-*:

---
const { title } = Astro.props;
---
 
<button class="share" data-title={title}>Поделиться</button>
 
<script>
  document.querySelectorAll<HTMLButtonElement>('.share').forEach((button) => {
    button.addEventListener('click', () => {
      const title = button.dataset.title;
      navigator.share({ title, url: location.href });
    });
  });
</script>

Значение пропса title попадает в HTML-атрибут, а скрипт читает его из dataset. В браузерах, где есть меню «Поделиться», нажатие откроет его с названием статьи. Уточнение <HTMLButtonElement> сообщает TypeScript, что найдены кнопки, — иначе редактор не знает о поле dataset.

Скрипт без обработки

Атрибут is:inline оставляет скрипт как есть: Astro не собирает его и вставляет на каждое место, где стоит компонент. Так подключают сторонние фрагменты, например код счётчика посещений. Скрипт из папки public/, подключённый через атрибут src, тоже помечают is:inline.

Частая ошибка

Ищут элемент через document.querySelector('button') и получают не ту кнопку — первую на странице, а не кнопку своего компонента. Давайте элементам компонента уникальный класс или атрибут data-* и выбирайте по нему.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.