Agent skill

Tabler Astro Component Scripts

by tabler in tabler/tabler

Rules for adding or fixing client-side scripts in Tabler's Astro components so the copied preview HTML stays readable, self-contained and runs in the right order.

MITAuto-check passedFrontend & Design

Install Tabler Astro Component Scripts

skills CLI
$ npx skills add tabler/tabler --skill astro-scripts -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install tabler/tabler astro-scripts --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/tabler/tabler.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/astro-scripts .claude/skills/astro-scripts && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
astro-scripts
GitHub stars
42k
Token cost
~2.1k tokens
SKILL.md length
979 words
Files
1
Skills in repo
21
Repo updated
First seen
Licence
MIT

At a glance

Rules for adding or fixing client-side scripts in Tabler's Astro components so the copied preview HTML stays readable, self-contained and runs in the right order.

  • Works in 10 steps: Never let Astro bundle a script → Where the script ends up → The standard snippet → …
  • Adding browser behavior to a Tabler Astro component
  • SKILL.md covers 1. Never let Astro bundle a…, 2. Where the script ends up, 3. The standard snippet and 4. Passing data with define:vars, plus 6 more sections
  • Calls pnpm

What it does

In the Tabler project the preview HTML is the product: people copy a page from `preview/dist` and expect its scripts to be readable and self-contained. The first rule is that Astro must never bundle a script, so every script uses the `is:inline` attribute and contains plain JavaScript with no type annotations or casts. `getElementById()` with a null guard replaces a cast, and the built page should be checked to confirm the code sits between its markers rather than in an `_astro` chunk.

Scripts render at the end of the body, after their markup and after the vendor libraries in the head. They travel through `CaptureScript`, the `addPageScript()` registry and `PageScripts` in the base and docs layouts. Registration must stay synchronous, the registry does not remove duplicates so two instances of a component emit two scripts that must be harmless, and the registry is keyed by `Astro.request` so concurrent renders never share scripts. The description adds guidance on `define:vars`, the IIFE trap, init timing and per-instance registries.

When your agent uses it

  • Adding browser behavior to a Tabler Astro component
  • Initialising a third-party library or Bootstrap plugin inside a component
  • Debugging an inline script that never runs in the built page
  • Moving a script out of a page and into a reusable component

Example prompts

  • “Add a copy-to-clipboard button to the code-snippet component and wire up its script.”
  • “The validator in the modal component never runs in the copied HTML. Find out why.”
  • “Initialise the date picker plugin in the form-date component without letting Astro bundle the script.”

Requirements

  • A checkout of the Tabler repository

Workflow steps

10 steps, taken from the step headings in SKILL.md.

  1. Never let Astro bundle a script
  2. Where the script ends up
  3. The standard snippet
  4. Passing data with define:vars
  5. No caller-supplied JS
  6. Instance registries
  7. Loading the library
  8. Prettier caveat
  9. Verify
  10. Checklist

What it can do on your machine

Read from SKILL.md and the folder at commit dcacb65. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • pnpm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pnpm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Tabler Astro Component Scripts loads about 2.1k tokens when it runs. Until then it costs about 131 tokens; SKILL.md has 979 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~131
When it runs · the whole SKILL.md, loaded when a task matches
~2.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from tabler/tabler at commit dcacb65, republished under its MIT licence (© tabler). 979 words, ~2,066 tokens.

Download SKILL.mdSave it as .claude/skills/astro-scripts/SKILL.md (or your agent's skills folder).
name
astro-scripts
description
Add or fix client-side JavaScript in a Tabler Astro component or page — plugin initialisation, Bootstrap wiring, anything that needs a `<script>` in the rendered HTML. Use whenever a component needs browser behaviour, a third-party library has to be initialised, an inline script does not run, or a script has to be moved out of a page. Covers `CaptureScript` / `PageScripts`, `script is:inline define:vars`, the IIFE trap, init timing, per-instance registries, and when a script must be assembled as a string.

Client-side scripts in Astro components

The preview HTML is the product: users copy a page out of preview/dist and expect the scripts in it to be readable and self-contained. That single fact drives every rule below.

1. Never let Astro bundle a script

Always <script is:inline>. A plain <script> is bundled, hashed, and moved into a module chunk — invisible in the copied HTML — and a plain <style> makes Astro stamp data-astro-cid-* on every element of the component.

An inline script is plain JavaScript. Type annotations, as HTMLInputElement, function (this: …) — anything the browser cannot parse — is the tell that a script is still being bundled, whatever the comment markers around it say. Two modal scripts shipped that way for months: the BEGIN / END comments wrapped nothing, and the copied modal had a validator that never ran. Use getElementById() with a null guard instead of a cast, and check the built page: the code must sit between its markers, not in a _astro/*.js chunk.

2. Where the script ends up

Scripts render at the end of <body>, not where the component sits, so they run after their markup and after the vendor libraries in <head>. The route:

text
<CaptureScript>  →  addPageScript()  →  page-scripts registry  →  <PageScripts />
  • shared/components/CaptureScript.astro captures its slot and registers it.
  • shared/layouts/BaseLayout.astro and docs/layouts/DocsLayout.astro drain the registry through <PageScripts />.
  • Registration is synchronous in CaptureScript's frontmatter on purpose: Astro renders siblings concurrently, so a script registered after an await can miss the drain. Do not make CaptureScript async.
  • The registry does not dedupe. Two instances of a component emit two scripts — write them so that is harmless (see section 6).
  • Both registries are keyed by Astro.request (a WeakMap, see shared/lib/page-scripts.ts). Astro renders pages concurrently in the build, the dev server and the html-diff / check-html crawlers, so a module-level array would hand one page's scripts to another. Keep it that way when touching the registry, and pass Astro.request from both the capture and the drain side.

Modals take the same route: <CaptureModal> → addPageModal() → shared/lib/page-modals.ts → <PageModals /> at the end of <body>, before the settings panel. Same rules: synchronous registration, keyed by Astro.request, no dedupe — a component that wraps a modal in CaptureModal and is rendered twice emits two modals with the same id, so such a component takes an id prop like a script does.

3. The standard snippet

astro
---
import CaptureScript from '../components/CaptureScript.astro'

interface Props {
  id: string
}

const { id } = Astro.props
const selector = `#wysiwyg-${id}`
---

<textarea id={`wysiwyg-${id}`}></textarea>
<CaptureScript>
  <!-- BEGIN WYSIWYG -->
  <script is:inline define:vars={{ selector }}>
    function initWysiwyg() {
      hugeRTE.init({ selector, height: 300 })
    }

    document.readyState !== 'loading' ? initWysiwyg() : document.addEventListener('DOMContentLoaded', initWysiwyg, { once: true })
  </script>
  <!-- END WYSIWYG -->
</CaptureScript>
  • BEGIN … / END … comments mark the block in the copied HTML. Use the component name in caps.
  • A named init… function plus the readyState guard, never a bare call: the script may be parsed after DOMContentLoaded has already fired.
  • The component takes a required id prop and derives ids and selectors from it in the frontmatter. Never query by class or by tag — a page renders many instances.

4. Passing data with define:vars

define:vars JSON-serialises the values and declares them as consts at the top of the script. It carries data only: no functions, no DOM nodes, no closures over frontmatter helpers. Pass config objects whole (chartOptions, markers, sortKeys) instead of interpolating them into a template string.

Two known snags:

  • Astro wraps a define:vars script in an IIFE. Anything the markup calls (onclick="setPageListItems(this)") must be assigned to window explicitly — see shared/components/demo/AdvancedTable.astro. If several instances define the same global, make it stateless and resolve the instance from the clicked element.
  • The type checker does not see define:vars bindings used inside template literals. shared/components/marketing/hero/Side.astro carries a // @ts-nocheck for exactly that; copy the comment with its explanation rather than restructuring the script.
Show full SKILL.md (414 more words)Show less

5. No caller-supplied JS

Never accept JavaScript as a string — no raw-JS props, no expressions in data files turned into code with new Function or set:html. They are eval sinks and block a strict CSP. Instead:

  • Page-specific behaviour goes in the page's own <CaptureScript> and reaches the plugin instance through its window.tabler_* registry (see preview/pages/signatures.astro).
  • Behaviour picked from data uses a whitelist of names mapped to real functions inside the script (see the chart x-formatter / y-formatter in shared/components/demo/Chart.astro).

6. Instance registries

Plugin instances go into a namespaced global keyed by id, so demo pages, docs examples, and the browser console can reach them:

js
window.tabler_rating ??= {}
window.tabler_rating[ratingKey] = new StarRating(ratingSelector, { … })

window.tabler_list, window.tabler_rating, … follow the same shape. Never store an instance in a bare global.

7. Loading the library

The library itself is not imported — it is a global loaded from libs.json:

  1. Check core/libs.json for the plugin (npm, js, css, head); add an entry if it is missing.
  2. Preview pages declare it on the layout: pageLibs={['nouislider', 'tom-select']} on DefaultLayout / BaseLayout.
  3. Docs pages declare it in front matter: docs-libs: apexcharts (and css-plugins: for extra tabler-*.css).

A component that silently assumes a global is a broken page whenever someone forgets the prop — say which lib it needs in a frontmatter comment and in the docs page.

8. Prettier caveat

prettier-plugin-astro cannot parse HTML comments or <script> tags inside a JSX expression ({cond && (<Fragment><!-- … --><script>…)}). Files that do this on purpose are listed at the bottom of .prettierignore. Prefer a plain (non-conditional) <CaptureScript> block so the file stays formattable; only add a new entry to .prettierignore when the conditional really is required, and keep it in the commented group.

9. Verify

An inline script that throws leaves the page looking fine but dead. Never hand one over unchecked:

  1. Start the dev server and open the page (astro-dev skill).
  2. read_console_messages — zero errors.
  3. Interact with the component (click, type) and confirm the behaviour, or read the instance back from window.tabler_* with javascript_tool.

10. Checklist

  • <script is:inline> inside <CaptureScript>, with BEGIN/END comments
  • Plain JavaScript inside: no type annotations, no casts, nothing the browser cannot parse
  • Required id prop; selectors derived from it, no class-wide queries
  • Data passed via define:vars, not string interpolation
  • init…() + readyState guard
  • Globals the markup needs assigned to window (IIFE trap)
  • Instance stored in a window.tabler_* registry keyed by id
  • Library present in core/libs.json and declared via pageLibs / docs-libs
  • Two instances on one page still work
  • Console clean in the browser; pnpm run format:prettier and pnpm run type-check clean

© tabler, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/astro-scripts of tabler/tabler.

Open the folder on GitHubat commit dcacb65

Compare with similar skills

Tabler Astro Component Scripts next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Tabler Astro Component Scripts compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Tabler Astro Component Scripts this skilltabler/tabler42k—~2.1kAutomated safety check: PassMIT
Migrate Webapi Selectallmicrosoft/power-platform-skills967—~5.3kAutomated safety check: NotesMIT
Sentry Browser SDKgetsentry/sentry-for-ai268—~6.5kAutomated safety check: NotesApache-2.0
Kill AI Slopyetone/kill-ai-slop1.3k—~1.4kAutomated safety check: PassApache-2.0
Pierre Trees File Treepierrecomputer/pierre6.2k—~473Automated safety check: PassApache-2.0
Motion Dev Animations199-biotechnologies/motion-dev-animations-skill1041 repos~2.8kAutomated safety check: NotesMIT

Similar skills

  • Migrate Webapi Selectall

    microsoft/power-platform-skills

    Official

    Reviews and migrates deprecated wildcard () values in Power Pages Web API fields site settings to least-privilege explicit Dataverse columns.

    967 GitHub stars~5.3k tokensUpdated today
    Frontend & DesignAuto-check: notes
  • Sentry Browser SDK

    getsentry/sentry-for-ai

    Official

    Full Sentry SDK setup for browser JavaScript. An agent skill from getsentry/sentry-for-ai.

    268 GitHub stars~6.5k tokensUpdated today
    Frontend & DesignAuto-check: notes
  • Kill AI Slop

    yetone/kill-ai-slop

    Find and remove AI slop — the generic, machine-default visual and copy tics of vibe-coded products — from a web project.

    1.3k GitHub stars~1.4k tokensUpdated 22 days ago
    Frontend & DesignAuto-check passed
  • Pierre Trees File Tree

    pierrecomputer/pierre

    Use when an app uses @pierre/trees to render or control a file tree, including React, vanilla JavaScript, SSR, web components, selection, search, rename, drag…

    6.2k GitHub stars~473 tokensUpdated today
    Frontend & DesignAuto-check passed
  • Motion Dev Animations

    199-biotechnologies/motion-dev-animations-skill

    Creates 120fps GPU-accelerated animations with Motion.dev (Framer Motion successor) for React, Next.js, Svelte, and Astro projects.

    104 GitHub starsUsed in 1 repo~2.8k tokens
    Frontend & DesignAuto-check: notes
  • HTML Coder

    TokenRhythm/opensquilla

    Guides semantic, accessible HTML work: pages, forms, media and HTML5 APIs, plus how to deliver a runnable webpage project with a preview.

    7.1k GitHub stars~1.4k tokensUpdated 2 days ago
    Frontend & DesignAuto-check passed

More from tabler/tabler

All 21 skills in this repo
  • Starts the right Tabler dev server, keeps it from clashing with builds and verifies changes in the browser before a page or component is handed back.

    42k GitHub stars~1.2k tokensUpdated today
    Auto-check passed
  • Sets the file structure, typing and Data API pattern for writing a new Bootstrap-style JavaScript component class in Tabler's vendored port of Bootstrap's JS.

    42k GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Writes or updates the classnames front matter that renders the class table at the end of a Tabler component docs page.

    42k GitHub stars~1.4k tokensUpdated today
    Auto-check passed
  • Guidance for changing the Tabler framework's own JavaScript in core/js: the tabler.js and tabler-theme.js bundles, the Bootstrap port and their tests.

    42k GitHub stars~1.4k tokensUpdated today
    Auto-check passed
  • Tabler Core SCSS

    tabler/tabler

    Rules for adding or changing styles in Tabler's core/scss framework: file placement, custom properties, dark mode, RTL, tests and build gates.

    42k GitHub stars~2k tokensUpdated today
    Auto-check passed
  • Builds or updates a Tabler component preview page under preview/pages, covering the page skeleton, header, and card grid conventions.

    42k GitHub stars~2.2k tokensUpdated today
    Auto-check passed

Works with

Questions about Tabler Astro Component Scripts

What does Tabler Astro Component Scripts do?

Rules for adding or fixing client-side scripts in Tabler's Astro components so the copied preview HTML stays readable, self-contained and runs in the right order. In the Tabler project the preview HTML is the product: people copy a page from `preview/dist` and expect its scripts to be readable and self-contained. The first rule is that Astro must never bundle a script, so every script uses the `is:inline` attribute and contains plain JavaScript with no type annotations or casts.

When should I use Tabler Astro Component Scripts?

Tabler Astro Component Scripts fits situations like: adding browser behavior to a Tabler Astro component; initialising a third-party library or Bootstrap plugin inside a component; debugging an inline script that never runs in the built page; moving a script out of a page and into a reusable component.

How do I install Tabler Astro Component Scripts in Claude Code?

Run `npx skills add tabler/tabler --skill astro-scripts -a claude-code`. Or copy the skill folder (.agents/skills/astro-scripts in tabler/tabler) into .claude/skills/astro-scripts in your project. Claude Code loads it when a task matches its description.

How do I install Tabler Astro Component Scripts in Codex?

Run `npx skills add tabler/tabler --skill astro-scripts -a codex`. Or copy the skill folder (.agents/skills/astro-scripts in tabler/tabler) into .agents/skills/astro-scripts in your project. Codex loads it when a task matches its description.

Can I use Tabler Astro Component Scripts in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add tabler/tabler --skill astro-scripts -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/astro-scripts, .gemini/skills/astro-scripts, .github/skills/astro-scripts and .opencode/skills/astro-scripts in your project.

What does Tabler Astro Component Scripts need to run?

Going by SKILL.md and its folder, Tabler Astro Component Scripts needs the command-line tools its instructions call (pnpm). Our summary lists: A checkout of the Tabler repository.

Does Tabler Astro Component Scripts access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Tabler Astro Component Scripts safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Tabler Astro Component Scripts use?

Tabler Astro Component Scripts is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Tabler Astro Component Scripts use?

About 2.1k tokens (SKILL.md is roughly 8.3k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Tabler Astro Component Scripts?

Skills that share tags, products or a category with Tabler Astro Component Scripts: Migrate Webapi Selectall (microsoft/power-platform-skills, 967 stars), Sentry Browser SDK (getsentry/sentry-for-ai, 268 stars), Kill AI Slop (yetone/kill-ai-slop, 1.3k stars) and Pierre Trees File Tree (pierrecomputer/pierre, 6.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Tabler Astro Component Scripts?

tabler (a GitHub organization) maintains it in tabler/tabler, which has 41,821 GitHub stars. The repository holds 21 skills in this directory. The repository was last updated on October 6, 2026.

Source: tabler/tabler on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.