MIT licensed UI component library for every RoxyAPI domain. Drop in a natal chart, kundli wheel, panchang table, dasha timeline, human design bodygraph, forecast timeline, numerology card, tarot spread, biorhythm chart, hexagram, or location search. Ship a finished astrology, human design, or forecast app without writing a single line of SVG, table layout, or form code.
Most data APIs leave you to build the visual layer yourself. Birth charts mean SVG geometry, panchang means complex tables, dasha means timelines, tarot means card layouts and reversed-card flips. We ship the finished components so you keep your time for product work.
Stateless. You fetch with the SDK, pass the response as the data prop, the component renders. No global stores, no setup.
Themed from design tokens. A handful of --roxy-* base tokens restyle every component in light and dark, and five named presets ship as one stylesheet each. Match any brand without rebuilding the bundle.
Charts open full size. A click on any drawn chart, or its toolbar button, opens it enlarged over the page.
Small, and capped in CI. Under 180 KB gzipped for every domain in one file, under 33 KB per component when imported individually. Both ceilings are enforced on every release, so the numbers cannot drift upward silently.
MIT licensed. Use it in commercial apps. No AGPL, no copyleft.
Designed for the developer who is great at backend or business logic but does not want to spend a week on chart geometry, the founder who does not want to hire a UI designer for a weekend project, and the AI agent that needs to render a structured astrology response without inventing markup.
Pick your path
You are building
Use this path
Time to live
A site you already have (Squarespace, Wix, Shopify, WordPress, Notion, Linktree) and you just want a ready-made widget that asks the visitor for what it needs and fetches for them
Plain HTML where you fetch the data yourself and pass it in
Path B: jsDelivr CDN, no build step
~30 seconds
Next.js + Tailwind + shadcn already set up
Path C: shadcn registry
~5 min
Not a developer, or you just want a live reading on an existing site with zero code? Use Copy-paste widgets below. Building an app in a framework? Path A (most developers pick this). Path C is a Path A accelerator that drops a typed React component file into your repo per component.
Copy-paste widgets (no code)
The same components run in a self-contained no-code mode: paste one snippet with a browser-safe publishable key and the widget asks for what the reading needs, or opens straight on a list when it needs nothing, fetches, and renders the result. Lists page on with Show more and open a picked entry in place, and a field that takes one entry by name is a search-as-you-type picker. No SDK call, no server, no build step. The walkthrough for site owners, the three delivery modes (hosted URL, iframe, script tag), platform guides, and the fix for a widget that shows an error all live on Copy-paste widgets. Every widget is styled and copied in the widget builder.
Path A: Next.js, Nuxt, and any other framework
1. Install
bash
npm install @roxyapi/ui-react
Building with Vue or Nuxt instead:
bash
npm install @roxyapi/ui-vue
@roxyapi/ui-react supports React 18 and 19, and @roxyapi/ui-vue supports Vue 3.3 and later. Both cover every component and take the same data prop. On first mount they load the component code from jsDelivr, pinned to the exact @roxyapi/ui release the package was built against, so your lockfile pins what renders. Behind a strict Content-Security-Policy, allow cdn.jsdelivr.net in script-src, or copy node_modules/@roxyapi/ui/dist/cdn/ to your own origin and call ensureScriptLoaded(ROXY_UI_VERSION, '/assets/roxy-ui') once at app entry (both exported by the React and Vue packages).
Any other framework (Svelte, Angular, Solid, Qwik, Astro) renders the elements natively: npm install @roxyapi/ui and use <roxy-natal-chart> directly. The React and Vue packages exist for typed props and idiomatic imports, not because the components need them.
Never expose a secret API key in client-side code. Call RoxyAPI from a server route, server action, or edge function. Anything in NEXT_PUBLIC_* ships to the browser and can be scraped.
3. Fetch and render in a Server Component
Every component in @roxyapi/ui-react ships with 'use client' inside, so a Next.js App Router Server Component fetches with your secret key and renders the component directly. No client file of your own, and the key never reaches the browser.
Add 'use client' only to a file of your own that holds state or passes an event handler such as onRoxyLocationSelect. Every response type is exported from the component package (import type { NatalChartResponse } from '@roxyapi/ui-react'), so you never declare your own interface and never install a second package just for types.
The Vue equivalent, for a Nuxt or Vite app. Fetch on the server exactly as above, then pass the response straight through:
In Nuxt, render them in any page or component, server rendered or not: the markup renders on the server and the element hydrates in the browser, with no <ClientOnly> needed. You do not need compilerOptions.isCustomElement.
First render shows a brief blank state while the component code loads from the CDN (under 180 KB gzipped). Render a skeleton or fallback while data is undefined for a polished feel.
Path B: Plain HTML (zero build step)
For a single page, an existing site, a WordPress shortcode, a Wix Embed HTML element, a Shopify theme, a Stan Store custom-code block, or a Linktree embed. This path fetches the data yourself and passes it to the component, so you control the exact request. If you would rather paste a ready-made widget that asks the visitor for what it needs and fetches for them, use Copy-paste widgets.
Open the file in any browser. The natal chart renders. Same pattern works in WordPress shortcodes, Shopify themes, Stan Store, Linktree, Notion, Bubble, Wix, Squarespace, or any builder that accepts custom HTML.
For browser-side calls, use a publishable key (pk_live_* / pk_test_*), not a secret key. List the domains you embed on as allowed origins on the key and a leaked key used from another domain returns 403. A key with no origins listed works from any site, fine for testing, so register your domains before going live. Get one at your account.
Pin the version in production
Snippets on this site load @latest. In production, pin the major version: @1 picks up every fix and never a breaking change. Pin an exact release such as @1.1.1 when you want byte-stable cache hits.
Keep every request on your own domain and your secret key on your server. One attribute routes a widget through you: submit-url names the route that answers every request it makes, the reading and the city search alike, and no key of any kind reaches the browser.
The widget POSTs { path, method, body, query } to submit-url. Your route calls https://roxyapi.com/api/v2{path} with your secret key and returns the JSON unchanged:
js
// POST /roxy/proxy
export async function POST(request) {
const { path, method, body, query } = await request.json();
const url = new URL(`https://roxyapi.com/api/v2${path}`);
for (const [k, v] of Object.entries(query ?? {})) if (v != null) url.searchParams.set(k, v);
const res = await fetch(url, {
method,
headers: { 'X-API-Key': process.env.ROXY_API_KEY, 'Content-Type': 'application/json' },
body: method === 'GET' ? undefined : JSON.stringify(body),
});
return new Response(res.body, { status: res.status, headers: { 'Content-Type': 'application/json' } });
}
The city search arrives the same way, as { "path": "/location/search", "method": "GET", "query": { "q": "...", "limit": 8 } }. To answer it on a separate route, add location-url: that route receives a GET with q and limit. Allow only the paths your page uses, so the route answers your widgets and nothing else.
To serve the script files too, download roxyapi-ui-{version}.tgz from the latest GitHub release (or take dist from the npm package, every file browsable in the current dist/cdn folder), and copy package/dist/cdn and package/dist/schemas to your server side by side, as they ship. Forms read their schemas from beside the script, and the language files sit in cdn/locales/.
On a PHP site, one open source file does all of this with no code to write: Self-Hosted Widgets for PHP keeps the widget files current on your server and relays every reading and city search with a publishable key locked to your domain.
Path C: shadcn registry (Next.js + Tailwind)
Already running shadcn? Install per-component. Each entry drops a typed React component file into components/roxy-ui/{name}.tsx and merges the CSS variable theme bridge into your globals.css so your existing shadcn theme drives RoxyAPI components automatically.
import { RoxyNatalChart } from '@/components/roxy-ui/natal-chart';
export default async function Page() {
const data = await fetchNatalChartFromYourServer();
return <RoxyNatalChart data={data} />;
}
The component file is yours. Open it and customize freely.
RoxyAPI components install under components/roxy-ui/, not components/ui/. Your shadcn button.tsx, card.tsx, input.tsx stay untouched.
What you can render
Every component takes a typed response from the matching endpoint. Pass the SDK response, the component figures out the rest.
Component
Domain
What it renders
<roxy-natal-chart>
Western astrology
Natal chart wheel with planet glyphs and aspect lines
<roxy-horoscope-card>
Western astrology
Daily, weekly, monthly, or yearly horoscope card
<roxy-synastry-chart>
Western astrology
Dual-wheel synastry plus inter-aspects table
<roxy-transit-wheel>
Western astrology
Natal chart on the inner ring, transiting bodies on the outer ring, aspect lines between them
<roxy-aspects-table>
Western astrology
Natal and transit aspects with chart-pattern detection
<roxy-moon-phase>
Western astrology
Moon phase card and calendar grid
<roxy-astrocartography-map>
Western astrology
Planetary lines (MC, IC, ascendant, descendant) over a world map
<roxy-relocation-wheel>
Western astrology
Relocated chart wheel plus a what-changes panel for a new city
<roxy-local-space-compass>
Western astrology
Azimuth compass of planetary directions from the birthplace
<roxy-positions-table>
Western astrology
Asteroids, Lilith, progressions, solar arc, or Arabic lots, columns adapt to the response
<roxy-fixed-stars>
Western astrology
Fixed-star conjunctions to natal planets and angles
<roxy-profection-card>
Western astrology
Annual profection: profected house, sign, and lord of the year
<roxy-vedic-kundli>
Vedic astrology
South, North, or East Indian kundli with an optional Chandra Lagna view
<roxy-panchang-table>
Vedic astrology
Tithi, vara, nakshatra, yoga, karana, plus muhurtas
<roxy-dasha-timeline>
Vedic astrology
Vimshottari mahadasha through prana, drill-down at every level
<roxy-dosha-card>
Vedic astrology
Manglik, Kalsarpa, Sade Sati severity, exceptions, remedies
<roxy-guna-milan>
Vedic astrology
36-point Ashtakoota with eight Koot sub-scores
<roxy-kp-planets-table>
Vedic (KP system)
KP planets with sub-lord and sub-sub-lord columns
<roxy-forecast-timeline>
Forecast
Cross-domain timeline of upcoming transits and events by date
<roxy-bodygraph>
Human Design
Nine-center bodygraph with type, authority, profile, channels, and gates
<roxy-hd-connection>
Human Design
Two-person connection chart of the channels they form together
<roxy-bazi-chart>
Chinese astrology
Four pillars in hanzi with hidden stems, Ten Gods, Na Yin, and element balance
<roxy-flying-star-chart>
Feng shui
Nine-palace flying star plate with the mountain, period, and water star per palace
<roxy-mayan-day-sign>
Mesoamerican astrology
Day sign and coefficient with the trecena and the Calendar Round
<roxy-vastu-mandala>
Vastu
Pada grid with a devata per square, the brahmasthan, and the entrance pada
<roxy-numerology-card>
Numerology
Life Path, Expression, Personal Year, full chart
<roxy-gematria>
Kabbalah
Values by cipher, every candidate Hebrew spelling, and equal-value words
<roxy-tarot-card>
Tarot
Single card with upright and reversed flip
<roxy-tarot-spread>
Tarot
Three-card, Celtic Cross, love, career spreads
<roxy-tarot-catalog>
Tarot
The 78-card deck as a gallery; a picked card opens in place
<roxy-biorhythm-chart>
Biorhythm
Daily bars, multi-day forecast, critical days
<roxy-dosha-constitution>
Ayurveda
Vata, pitta, and kapha shares with the dominant dosha and the factors behind it
<roxy-hexagram>
I Ching
Hexagram with trigrams, judgment, image, changing lines
<roxy-crystal-grid>
Crystals
Crystal gallery, filterable by chakra, zodiac sign, element, colour, or planet
<roxy-crystal-card>
Crystals
One crystal with its meaning, chakras, signs, and pairings
<roxy-dream-search>
Dreams
Dream dictionary with an A to Z bar and search; a picked symbol opens in place
<roxy-dream-card>
Dreams
Dream symbol meaning and full interpretation
<roxy-angel-number-card>
Angel Numbers
Angel number meaning with spiritual, love, and career sections
<roxy-reference-card>
Reference
Glossary card for any sign, planet, rashi, gate, center, or number lookup
<roxy-compatibility-card>
Cross-domain
Score card with category breakdown
<roxy-location-search>
Helper
Debounced city search, fires roxy-location-select event
<roxy-endpoint-form>
Helper
Schema-driven form for any endpoint
These are the most used. Every component, with its endpoints, attributes, and part names, is in the machine-readable components catalog.
Full live preview of every component at roxyapi.github.io/ui. Click any component for a Preview tab and a copy-paste Code tab.
Languages and localization
RoxyAPI components render in 10+ languages: English, Turkish, German, Spanish, Hindi, Portuguese, French, Russian, Simplified Chinese, and Traditional Chinese. A component picks its language up from the page it is embedded in, so a site already published in Spanish or Hindi usually needs no configuration at all.
The language is chosen in this order, and the first answer wins:
A lang attribute on the component itself.
A lang attribute on any element around it, so one container can set a whole section.
The lang attribute on the page, which is what most site builders already emit (<html lang="es">).
That is why the code from the widget builder and the component catalog carries no lang by default. Paste one onto a Spanish page and it renders in Spanish. Set lang yourself only when you want to fix the language regardless of the page, for example an English reading on an otherwise German site.
Load the labels for your language
Written readings arrive in your language automatically. The labels the component writes itself, such as headings, tab names, and table captions, live in a small separate file, one per language, so an English site downloads nothing extra. Add one line for the language you want:
The widget builder, under Content, and the component catalog both have a language selector. Pick a language there and the snippet you copy already carries the right line.
Hosted embeds
The hosted embed URL takes lang on the query string and handles both halves for you, so nothing else is needed:
An iframe is its own page, so it has nothing to inherit from. Without lang a hosted embed renders in English even on a Spanish site.
What is translated, and what is not
Being straight about this saves you a support ticket:
Readings and interpretations follow the language on every endpoint. So do the planet, sign, aspect, and house names that come back with them.
On-screen labels follow it in German, Spanish, French, Hindi, Portuguese, Russian, and Turkish, once the label file for that language is loaded. A card reads its own labels fully in your language or fully in English, never a mixture, so a page is never blank or half-rendered.
Column headings on the generic data tables follow it too, for every field name the API publishes a translation for. A name without one reads in plain English, and the values inside the columns follow the language either way.
The visitor-facing form a widget draws for itself follows the language too, including its field labels and its dropdown options, so a Spanish page collects Fecha de nacimiento rather than Birth date. On a non-English page the form leaves out the English reference help text rather than mix languages.
Fixing a language turns the page inheritance off. A component with an explicit lang ignores the page it sits on, which is the point, but it also means a later site-wide language change will not reach it.
A regional tag works.es-AR uses the Spanish labels and Argentinian date and number formatting. A language RoxyAPI does not cover falls back to English rather than failing.
Theming
Every component takes every colour, size, space, radius, and font from a --roxy-* design token. Custom properties cross the Shadow DOM boundary, so a value set on :root reaches every component below it. Only a few tokens are bases, and everything else derives from them, so a handful of lines restyle the whole library:
--roxy-bg is the page colour and --roxy-fg the ink: the card, the secondary ink, the muted text, and every hairline derive from those two, so a warm or brand palette carries through without setting them one by one. --roxy-accent moves every accent mark and the focus ring, --roxy-radius every corner. --roxy-font-sans is unset by default, so components inherit your page font until you set it. The card is flat on the page by default; set --roxy-surface only to lift it off.
Dark mode needs no wiring. Components follow the system preference, a .dark class, or data-theme="dark" on the document, any ancestor, or the element itself. If your theme lives on a container element instead of <html>, put data-theme="light" or data-theme="dark" on that same element so every token you did not set follows your mode, not the visitor operating system.
Or override per element to deviate one component without touching the rest:
Every derived token can still be set directly, and your value wins. To make a component read as part of your page rather than a card dropped onto it, bridge the bases to the tokens you already have: hold references (--roxy-bg: var(--background)), declare them once so your dark block moves them with everything else, and include the font and radius tokens so type and corners match too. Two open source templates ship that bridge in full, with a test that keeps it honest: the AI chatbot on a dark theme and the AI companion on a light and dark pair. The full reference, with the light and dark default for every token and what each one paints, is THEMING.md in the component repo. It is maintained alongside the components, so it never lags a release; the literal defaults ship in the package as tokens.css. It also carries ready-made patterns for dark mode, high contrast, per-domain accents, and a Tailwind token map.
The live preview at roxyapi.github.io/ui has a Theme menu that applies any preset and a Customize colors dialog, a picker per colour token that outputs a CSS block you paste into your project.
Named presets
Each preset is one optional stylesheet with a light and a dark palette that restyles every component on the page. Link one after the component script:
Ink blue on cream, gold on night blue in dark mode, serif headings
Celeste
celeste.css
The roxyapi.com look: near-black ink on near-white, a teal accent, the system font, crisp corners
All five sit in dist/styles/themes/, and the themes list in the components catalog names each one. Your own --roxy-* declarations still win over a preset.
Chart size
Every drawn chart (a wheel, a kundli, a bodygraph, a compass, a mandala) opens enlarged from its toolbar or with a mouse click on the drawing. Two tokens size them: --roxy-chart-max-width caps the chart inside its card, on :root for every chart or on one element, and --roxy-chart-expanded-width sets the width of the enlarged view (60rem by default).
Already on shadcn?
Path C installs a thin bridge that maps your existing shadcn --card, --background, --foreground, --muted-foreground, --primary, --border, --destructive, and --radius onto the RoxyAPI tokens. Your shadcn theme drives RoxyAPI components automatically. Path A and Path B users can ship the core of the same bridge as a small CSS file:
Components are not all-or-nothing. Every structural block carries a part name, so you can restyle it, hide it from a stylesheet, or drop it from one placement with an attribute.
Target any block with ::part()
part names are the same in every component, so one rule covers the whole library. ::part(aspects) reaches the aspect grid on a natal chart and the aspect list on an aspects table alike.
css
/* Restyle one block. */
roxy-natal-chart::part(card) { border: 0; box-shadow: none }
/* Or remove it. */
roxy-natal-chart::part(patterns) { display: none }
Common names are card, header, chart, legend, details, table, readings, and patterns, plus form, loading, error, empty, hint, edit-bar, and attribution on the built-in states. Every structural section carries section plus its own name, so you can style all of them at once or one by one. To find the name for a block, open your browser inspector and read its part attribute.
hide-readings: keep the chart, drop the words
Set it when your own copy supplies the interpretation. The prose is left out of the markup entirely, so the page never ships text it is not showing.
Wheels, maps, tables, grids, legends, badges, and every number stay. It is off by default.
hide-sections: remove a whole block
hide-readings draws its line on the content, not on the block, so a block made of measurements stays even when it reads like analysis. A natal chart pattern reports its figure, element, modality, tightness, and member planets, so it survives on purpose. To remove the block itself, name it:
It takes a comma-separated list of part names and applies to every component, so a name it does not recognize is simply ignored rather than breaking the render. Use ::part() when one rule should cover a whole site, and hide-sections when two components on the same page need to differ.
On a hosted embed
Both work as query parameters, which is the only way to reach them through an iframe:
hide-readings is a switch, so any value turns it on. Leave the parameter off to keep the readings.
attribution: the credit line is yours to switch on
No component draws a RoxyAPI credit unless you ask for one, so a page renders under your brand alone. To name your source, a small "Spiritual data by RoxyAPI" link appears under a reading a component fetched for itself, in the language of the page:
A component you pass data to never draws it, and ::part(attribution) styles it where it does appear.
Wiring custom events
Some components dispatch typed events: roxy-submit, roxy-location-select, roxy-validation-error, roxy-render-error, and roxy-spec-error. The React package types them as handler props, such as onRoxyLocationSelect.
The full walkthrough, for the Vercel AI SDK and for the Anthropic, OpenAI, and Gemini connectors, is the AI astrology charts in chat tutorial. This section is the short version.
The model never calls a widget. It calls a RoxyAPI tool over Remote MCP exactly as it does today, and the tool result comes back into your app as a message part: the tool name the model used plus the JSON string the tool returned. Your interface, not the model, maps that name to a component and sets data. So the model needs no component names, no list of which tools have a chart, and no UI instructions in its prompt; the same JSON these components already take is what arrives, which is why they double as generative UI for AI chat. Four lines put it on screen:
Find the tool name and the result text in whatever your chat framework or model API hands you.
JSON.parse the text.
componentForTool(name) for the component.
Set data.
componentForTool is exported from @roxyapi/ui, @roxyapi/ui-react, and @roxyapi/ui-vue, and returns { tag, pascal, attrs, operationId, toolName }, or undefined for a tool no component covers, so a reference lookup keeps answering in prose instead of breaking.
tsx
'use client';
import * as RoxyUI from '@roxyapi/ui-react';
import type { ElementType } from 'react';
export function ToolWidget({ toolName, resultText }: { toolName: string; resultText: string }) {
const binding = RoxyUI.componentForTool(toolName);
if (!binding) return null;
const Widget = RoxyUI[binding.pascal as keyof typeof RoxyUI] as ElementType;
return <Widget data={JSON.parse(resultText)} {...binding.attrs} />;
}
The same thing in plain HTML, with the CDN bundle:
html
<script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js" defer></script>
<script>
function renderToolResult(toolName, resultText) {
const binding = RoxyUI.componentForTool(toolName);
if (!binding) return;
const el = document.createElement(binding.tag);
el.data = JSON.parse(resultText);
document.body.append(el);
}
</script>
The compact response shape is decoded inside the component, so leave it on and pass the result straight through. expandCompact is exported from the same three packages when your own code wants the plain object.
Any chat UI where you control the markup for a tool result can host these components: the Vercel AI SDK and AI Elements, assistant-ui, CopilotKit, or a hand-rolled one. OpenAI ChatKit is the exception, because its widgets are a closed declarative schema of cards and fixed nodes with no slot for a custom component. The open source chatbot template is the worked example: one file maps the message parts, one file renders them.
Common gotchas
[object Object] in the rendered chart
You passed the SDK envelope instead of the unwrapped response.
The API call is failing silently. Open the network tab and read the code in the response body. A 401 almost always means the key never reached createRoxy(...), and a 403 means a publishable key was called from a site missing from its allowlist, fixed at your account. The key and origin codes:
The calling site is not on the origin allowlist of this publishable key.
A 429 is either the per-minute limit (rate_limit_per_minute, retry after Retry-After) or the used up monthly allowance (rate_limit_exceeded), so read code. Every other code is on the error codes page.
'use client' errors in Next.js App Router
Components from @roxyapi/ui-react carry 'use client' themselves, so a Server Component imports and renders them directly (see Path A). The error comes from your own file: add 'use client' at the top of any file that holds state or passes an event handler such as onRoxyLocationSelect.
Empty page on first paint
Expected. The React and Vue packages load the component code from the CDN (under 180 KB gzipped) on mount. Render a fallback while data is null, or preload the bundle in your <head>:
Components work locally but break on GitHub Pages or any sub-path host
You used origin-absolute paths (/something). Use relative paths (./something) or set <base href="./">.
Tarot card images return CORS errors
The component reads imageUrl from the response. Either serve those images from your own CDN, or set Cross-Origin-Resource-Policy: cross-origin on your image host.
Verification checklist
After integrating, confirm:
No [object Object] strings in any chart, table, or card.
No "Loading..." that never resolves.
Browser console has no errors and no warnings.
Dark mode flips when you toggle [data-theme="dark"] on <html>.
Production build (npm run build) compiles without errors.
The key in any client-bundled code is a publishable key, not a secret one.
Where to go next
Live customizer at roxyapi.github.io/ui. Theme presets, colour pickers, copy-paste integration snippets, every component rendered against real responses.
GitHub at github.com/RoxyAPI/ui. MIT licensed. Release notes, runnable examples, and issues.
Catalog page at roxyapi.com/ui for distribution surfaces and FAQ.
SDK reference at /docs/sdk for every endpoint method.
Yes. Components are stateless. Fetch with fetch, axios, your favorite client, your own server proxy, anything. Pass the response as the data prop.
Does it support React Native or Flutter?
Not yet. Web (browsers and webviews) only as of 2026.
What languages does RoxyAPI UI support?
10+ languages: English, Turkish, German, Spanish, Hindi, Portuguese, French, Russian, Simplified Chinese, and Traditional Chinese. Readings and the planet, sign, and aspect names come back in the language you ask for. On-screen labels follow it in German, Spanish, French, Hindi, Portuguese, Russian, and Turkish once that label file is loaded.
How do I show a chart in Spanish?
Add one line beside the component script, pointing at the Spanish labels: https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/locales/es.js. If the page itself is Spanish, that is all you need, because a component reads the language off the page it is embedded in. If the page is in another language, add lang="es" to the component as well.
Do I have to set the language on every widget?
No. A component reads the lang attribute on the page it is embedded in, so a Spanish or Hindi site localizes with no per-widget change. Set lang on a component only when you want to fix its language regardless of the page.
Why is my chart in Spanish but the headings are still English?
The labels a component writes itself ship as a separate file per language, so English sites download nothing extra. Add the line for your language, shown in Languages and localization above, and the headings follow.
Are the widget input forms translated?
Yes. Field labels and dropdown options follow the same language as the reading, so a visitor on a Hindi page sees जन्म तिथि rather than Birth date. Load the label file for your language exactly as shown in Languages and localization above, or use the hosted embed URL with lang, which loads it for you. On a non-English page the form leaves out the English reference help text, so it reads in one language.
Will my brand colors work?
Yes. Set the --roxy-* base tokens (--roxy-bg, --roxy-fg, --roxy-accent) on :root or per element, or link one of the five named presets. The live preview has a Customize colors dialog that exports a CSS block.
Can I show the chart without the written interpretation?
Yes. Set hide-readings on the component (hideReadings in React and Vue) and the interpretive prose is left out of the markup entirely, while the wheel, tables, legends, and every number stay. Use it when your own copy supplies the words.
Can I remove one block, like the chart patterns?
Yes, two ways. roxy-natal-chart::part(patterns) { display: none } in your stylesheet covers every placement on the site, and hide-sections="patterns" on a single component covers just that one, which is what you want when two charts on the same page need to differ. Both take the part names components publish, listed in Choosing what a component renders above.
Do I need a separate UI/UX designer?
No. The components ship with sensible defaults out of the box. Theme to your brand colors and you are done.
Can an LLM render these from a tool call?
Yes. Pass the tool name to componentForTool() and the parsed tool result as data, and the matching chart, spread, or card renders beside the reply. It works in any chat UI where you control the markup for a tool result, and the compact response shape is decoded for you. Walkthrough: AI astrology charts in chat.
Can AI coding agents use this?
Yes. Cursor, Claude Code, GitHub Copilot, Codex, and any agent reading your package.json will see @roxyapi/ui and the standard component names. Path C drops typed component files into your repo, which makes agent navigation even easier. Before installing, an agent reads the full component reference as raw markdown at https://raw.githubusercontent.com/RoxyAPI/ui/main/AGENTS.md; fetch it whole with curl -s, not a summarizing web tool.
How big is the bundle?
Under 180 KB gzipped for the full bundle from the CDN, under 33 KB per component when imported individually from @roxyapi/ui/components/{name}. Both are CI-enforced ceilings, so they hold from release to release.
Is there a TypeScript type for the response shape?
Yes. The SDK ships full types, and the React and Vue packages export every response type their components accept. The component data prop is typed against the matching endpoint response. Your IDE catches schema drift before runtime.
What if my endpoint is not in the component list?
The catch-all <roxy-data> element renders any response shape as a structured table. New endpoints work out of the box; bespoke components ship as the catalog grows.
R
RosieYour AI guide to RoxyAPI
R
Hi, I am Rosie, your guide to the RoxyAPI insight tools.
Ask me to read your birth chart, pull a card, or map your numbers, and I will interpret what it means for you. Unlike most AIs, I never make the numbers up: every reading runs on real, verified calculations. Curious about the API, pricing, or docs instead? Ask me that too.