# Web components

`@astroway/ui` is a set of plain custom elements: put a tag on the page and it draws itself. Charts are drawn by [`@astroway/render`](https://www.npmjs.com/package/@astroway/render), the same code behind `/v1/render/*`, so a wheel on your page matches the wheel the API returns.

The package is in **alpha** (`0.1.0-alpha.1`): attribute names may still change before 1.0. Package page: [npm](https://www.npmjs.com/package/@astroway/ui), source: [GitHub](https://github.com/astroway/astroway-ui).

## Install

From a CDN, no build step:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@astroway/ui/dist/cdn/index.js"></script>
<aw-moon-phase></aw-moon-phase>
```

Or from npm, importing every element or just the ones you use. The package is still in alpha, so ask for that tag:

```bash
npm install @astroway/ui@alpha
```

```js
```

## Three ways to feed an element

**A. Your data.** Fetch on your server with your own key and hand the element the JSON. No request leaves the visitor's browser, so any key class works.

```js
document.querySelector('aw-natal-wheel').data = chart; // the data of a /v1/chart response
```

A server template can write the same JSON into the attribute instead:

```php
<aw-natal-wheel data='<?= htmlspecialchars(json_encode($chart), ENT_QUOTES) ?>'></aw-natal-wheel>
```

**B. Keyless.** Elements backed by `/v1/public/*` need no key. They share the visitor's public budget of 30 units an hour per IP; when it runs out the element says how long to wait.

```html
<aw-moon-phase lang="en"></aw-moon-phase>
<aw-horoscope sign="leo" period="daily"></aw-horoscope>
<aw-tarot-spread spread="three-card"></aw-tarot-spread>
```

**C. Publishable key.** Elements backed by keyed endpoints take a `pk_` key made for your site: its origin list, a credit cap and an endpoint scope are required when you create it. See [Keys for the browser](/en/authentication/#keys-for-the-browser). A secret `aw_` key is refused before any request is made.

```html
<aw-natal-wheel api-key="pk_live_..." date="1990-05-15" time="14:30"
  latitude="50.45" longitude="30.52" timezone-offset="3"></aw-natal-wheel>
```

For these elements the key's scope needs `chart`, plus `chinese/zodiac/animal` if you use `aw-chinese-sign`. The origin list is matched by host: a key for `example.com` also works on `http://example.com:8080`.

## React and Next.js

React 19 renders custom elements directly. Two things differ from plain HTML:

- React keeps `key` for itself, so pass the key as `api-key`.
- On a server-rendered page, pass layer A data as a string. React drops object props during server rendering and does not set them while hydrating.

```tsx
'use client';

  return <aw-natal-wheel data={JSON.stringify(chart)} />;
}
```

The modules can be imported on the server: the tag goes out as plain HTML and draws once the browser loads the element.

## Elements

| Element | Ways | Source |
|---|---|---|
| `aw-natal-wheel` | A/C | `/v1/chart` |
| `aw-aspect-grid` | A/C | `/v1/chart` |
| `aw-planet-table` | A/C | `/v1/chart` |
| `aw-moon-phase` | A/B | `/v1/public/moon-phase` |
| `aw-planet-of-day` | A/B | `/v1/public/planet-of-day` |
| `aw-horoscope` | A/B | `/v1/public/horoscope/{daily,weekly,monthly}` |
| `aw-tarot-card`, `aw-tarot-spread` | A/B | `/v1/public/tarot/*` |
| `aw-sign-matrix` | A/B | `/v1/public/compatibility/matrix` |
| `aw-synastry-score` | A/B | `/v1/public/synastry` |
| `aw-chinese-sign` | A/C | `/v1/chinese/zodiac/animal` + `/v1/public/chinese/zodiac/texts` |

Elements that share a chart on one page (a wheel, a table and a grid with the same birth data) make one request between them.

`aw-aspect-grid` is about 560 px wide at its own size. In a narrower column it scales down and the orb labels get small; add `scroll` to keep it at full size with sideways scrolling.

## Language, theme, errors

- `lang` takes any of the [21 languages](/en/languages/) and falls back to the page's `<html lang>`. Names come from the API's `localized` tables.
- `theme="dark"` switches the drawing; colours follow CSS custom properties `--aw-accent`, `--aw-fg`, `--aw-bg`, `--aw-bg-soft`, `--aw-border`.
- Every element fires `aw-error` with `{ kind, message }`, where `kind` is `error`, `rate-limited` or `key`.
