Astro integration
NEW@love-rox/tcy-astro
Astro 4+ only. Auto-registers the rehype plugin on Astro's Markdown / MDX pipeline, and ships a `<Tcy>` component for `.astro` files.
Install
Peer dependency: astro >= 4. @love-rox/tcy-core and @love-rox/tcy-rehype are pulled in automatically.
bun
bun add @love-rox/tcy-astropnpm
pnpm add @love-rox/tcy-astronpm
npm i @love-rox/tcy-astroyarn
yarn add @love-rox/tcy-astroTwo pieces
tcy() integration
Registers @love-rox/tcy-rehype on Astro's Markdown / MDX pipeline so half-width alphanumerics in your .md and .mdx content are wrapped automatically at build time.
<Tcy> component
An Astro component to wrap a slot inside .astro files explicitly — useful for body content authored directly in .astro, outside the Markdown pipeline.
Usage
Register the integration in astro.config.mjs. That alone makes Markdown / MDX content tate-chu-yoko-aware.
// astro.config.mjs
import { defineConfig } from "astro/config";
import tcy from "@love-rox/tcy-astro";
export default defineConfig({
integrations: [tcy()],
});With options
Forward any rehype-tcy options through the integration call.
// astro.config.mjs
import { defineConfig } from "astro/config";
import tcy from "@love-rox/tcy-astro";
export default defineConfig({
integrations: [
tcy({
maxLength: 2,
excludeWords: ["URL", "API", "2026"],
}),
],
});Inside an `.astro` file
For body content authored directly in .astro (no Markdown in the picture), use the <Tcy> component.
---
import Tcy from "@love-rox/tcy-astro/Tcy.astro";
---
<p style="writing-mode: vertical-rl">
<Tcy>第1章 2026年4月、Webの縦書きは進化した。</Tcy>
</p>Options
The shared options behave exactly as they do in the React / Vue / rehype adapters. There's just one integration-only knob.
Shared options + rehype passthrough
| Option | Type | Default | Description |
|---|---|---|---|
| target | 'alphanumeric' | 'alpha' | 'digit' | 'ascii' | RegExp | 'alphanumeric' | What counts as a tate-chu-yoko target. alphanumeric matches [0-9A-Za-z]; ascii covers printable ASCII. A custom RegExp is accepted. |
| combine | boolean | true | Merge consecutive target characters into a single span. Set to false to wrap each character individually. |
| include | string | string[] | undefined | Extra characters to treat as targets regardless of target. |
| exclude | string | string[] | undefined | Characters to exclude. Takes precedence over include. |
| maxLength | number | undefined | Maximum length for a tcy segment. Runs longer than this are demoted back to plain text — for example maxLength: 2 keeps single digits and pairs uprighted while leaving four-digit years like 2026 lying on their side. |
| excludeWords | string[] | undefined | Exact words to exclude from tcy wrapping. Matched against the whole segment value (not a substring) — useful for keeping acronyms like URL / API or specific years out of the upright treatment. |
| tagName | string | 'span' | Tag name used for wrapping. |
| className | string | string[] | 'tcy' | Class name(s) applied to the wrapping element. Pass an array for multiple classes. |
| skipTags | string[] | ['code', 'pre', 'script', 'style'] | Tags whose subtrees are left untouched. Code/pre/script/style content is skipped by default. |
Integration-only
| Option | Type | Default | Description |
|---|---|---|---|
| markdown | boolean | true | Whether to register rehype-tcy on the Markdown / MDX pipeline. Set to false to opt out (e.g. if you only want the <Tcy> component). |
Behavior notes
- Astro is SSG-first, so both pieces run at build time — there's no client-side cost.
- Text inside
<code>/<pre>/<script>/<style>is skipped by default (configurable viaskipTags). - Idempotent. Rebuild the same Markdown as many times as you want; the output HTML doesn't drift.
- The
<Tcy>component delegates to the sametcy-rehypeunderneath, so Markdown content and.astro-authored content behave identically.
Other adapters
Not using Astro? Drop the [rehype plugin](./rehype) directly into your unified pipeline. Need runtime wrapping in the app? Use the [React](./react) or [Vue](./vue) component.