---
title: Astro
description: Render Timeless anatomy on the server and register behavior in the browser.
editUrl: true
head: []
template: doc
sidebar:
  order: 4
  hidden: false
  attrs: {}
pagefind: true
draft: false
---

## Install

```sh
pnpm add @timelessui/components
```

## CSS and registration

Import component CSS in an Astro layout or page frontmatter:

```astro
---
import '@timelessui/components/css/tokens.css'
import '@timelessui/components/css/core/button.css'
import '@timelessui/components/css/core/floating.css'
import '@timelessui/components/css/core/popover.css'
import '@timelessui/components/css/themes/atmosphere/tokens.css'
import '@timelessui/components/css/themes/atmosphere/button.css'
import '@timelessui/components/css/themes/atmosphere/popover.css'
---
```

Render the public anatomy as ordinary Astro markup, then load the definition as a processed client
script:

```astro
<ui-popover>
  <button data-ui-part="trigger" type="button" popovertarget="details">Open</button>
  <div id="details" popover="auto">Popover content</div>
</ui-popover>

<script>
  import '@timelessui/components/register/ui-popover'
</script>
```

## SSR and hydration

Astro renders the complete Light DOM on the server. A custom element does not need an Astro client
directive. The processed script registers it in the browser, then native custom-element upgrade
enhances the existing DOM. Class-only imports are SSR safe.

## Attributes, properties, events, and TypeScript

Use plain attributes for authored state. Assign live properties from a client script after selecting
the element. Listen for namespaced events with `addEventListener`, and import element or event
detail types from the matching package entrypoint when the script uses TypeScript.

Astro templates are HTML, not JSX, so no JSX declaration applies to them. Completion and hover
documentation for `ui-*` tags, their attributes, and their permitted values come from the shipped
editor data instead — see [Editor setup](/docs/getting-started/editor-setup/). If a page uses a
React, Preact, or Solid island, import that framework's declarations for the island's `.tsx` files.

CSS-only components are a root class plus `data-ui-*` on a native tag. Astro spreads attributes, so
the typed helper works directly in a template:

```astro
---
import { uiAttributes } from '@timelessui/components/attributes'
---

<button {...uiAttributes('button', { variant: 'primary' })} type="button">Publish</button>
```