Vue 3 adapter

@love-rox/tcy-vue

A `<Tcy>` component for Vue 3. Same options and same behavior as the React adapter — drops straight into a Vue app.

v0.3.0MITvue 3.x

Install

@love-rox/tcy-core comes along as a dependency — no separate install needed.

bun

bun add @love-rox/tcy-vue

pnpm

pnpm add @love-rox/tcy-vue

npm

npm i @love-rox/tcy-vue

yarn

yarn add @love-rox/tcy-vue

Usage

Import in <script setup> and use <Tcy> as a child of a vertically-written parent. Only string slot content is rewritten; element nodes are walked recursively without being touched.

Vue 3vue
<script setup lang="ts">
import { Tcy } from "@love-rox/tcy-vue";
</script>

<template>
  <p style="writing-mode: vertical-rl">
    <Tcy>第1章 2026年4月、Webの縦書きは進化した。</Tcy>
  </p>
</template>

Options

The Vue component accepts the exact same options as the React component. Shared options also line up 1:1 with the rehype and Astro adapters.

Shared options

OptionTypeDefaultDescription
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.
combinebooleantrueMerge consecutive target characters into a single span. Set to false to wrap each character individually.
includestring | string[]undefinedExtra characters to treat as targets regardless of target.
excludestring | string[]undefinedCharacters to exclude. Takes precedence over include.
maxLengthnumberundefinedMaximum 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.
excludeWordsstring[]undefinedExact 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.

Component-only props

OptionTypeDefaultDescription
classNamestring'tcy'Class applied to each generated span.
askeyof JSX.IntrinsicElements'span'Tag name used for wrapping.

Behavior notes

  • Runs are not joined across element boundaries — <em>12</em>34 produces two separate spans.
  • Full-width alphanumerics (A–Z / 0–9) are left alone because they already render upright in vertical text.
  • SSR-safe — works under Nuxt 3 and other Vue SSR setups; server and client emit the same DOM.
  • Walks the slot's VNode tree recursively, only wrapping text nodes.

Other adapters

Using React? The React adapter has the same API. On a Markdown / Astro pipeline? The rehype and Astro adapters do this at build time, with no Vue dependency in the bundle.