Skip to content
Docs
    Menu

    Site code reference

    Interactivity

    Add interactive behavior to a Starjay site with scripts and built-in HTML elements, site-wide or per component.

    Starjay sites add behavior with plain browser features. React and other framework components aren't supported (see What isn't supported).

    Use HTML first

    Many common patterns need no script at all:

    • Accordions and FAQs: <details> and <summary>.
    • Dialogs and modals: <dialog>, opened with one line of script.
    <details class="border-b border-ink-200 py-4">
      <summary class="cursor-pointer font-display text-lg text-ink-900">Do you ship abroad?</summary>
      <p class="mt-2 text-ink-700">Yes, to most countries.</p>
    </details>

    Add a script to a component

    Put a <script> at the end of the component. Astro bundles it, runs it as a module, and includes it once per page even when the component appears several times, so select elements by attribute rather than by a single id:

    <div data-component="MenuToggle">
      <button type="button" data-menu-button class="md:hidden" aria-expanded="false">Menu</button>
      <nav data-menu class="hidden md:block">
        <slot />
      </nav>
    </div>
    
    <script>
      function setUpMenus() {
        document.querySelectorAll('[data-component="MenuToggle"]').forEach((root) => {
          const button = root.querySelector('[data-menu-button]')
          const menu = root.querySelector('[data-menu]')
          button?.addEventListener('click', () => {
            const open = menu?.classList.toggle('hidden') === false
            button.setAttribute('aria-expanded', String(open))
          })
        })
      }
      setUpMenus()
      document.addEventListener('astro:after-swap', setUpMenus)
    </script>

    Pages that swap without a full reload

    The Client-Side Router setting is on by default: moving between pages swaps the content without a full reload. A bundled script then runs only once, on the first page a visitor opens. Run your setup code once directly and again on Astro's astro:after-swap event, as above, so it also runs after every page change. With the setting off, every navigation is a full page load and the direct call is enough. See Page transitions and navigation.

    Add behavior to every page

    Put site-wide scripts in src/body/BodyEnd.astro instead of repeating them in every component: scroll animations, dark mode, a cookie banner, a back-to-top button, a chat widget. A snippet file can import components, so you can render <CookieBanner /> there. See Head and body snippets.

    Add a third-party snippet

    Analytics tags, embeds and widgets usually come as a <script> you paste in. Astro processes scripts by default; add is:inline so it runs exactly as written:

    <script is:inline async src="https://widgets.example.com/chat.js"></script>

    Third-party scripts that belong in the <head> go in src/head/HeadEnd.astro. For Google Analytics, use the built-in setting instead; see Google Analytics.