use-list-format
Join strings into a locale-aware list with Intl.ListFormat ("a, b, and c", "a、b、c", "a, b or c").
| Package | @vizejs/composable/use-list-format |
| Own the source | vize lib pull composable:use-list-format |
| Runtime exports | useListFormat |
| Gzip budget | 2048 B |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/composable
Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.
import { useListFormat } from "@vizejs/composable/use-list-format";
Try it
Announce a list of speakers
Join a changing list of names into one sentence with the conjunction and punctuation of the reader's language.
What to observe: The speakers read Ada, Grace, and Linus. Choose German (Germany) for Ada, Grace und Linus, and Japanese (Japan) for Ada、Grace、Linus. Add and remove speakers to see one, two, and many names.
The list is a ref that is reassigned, not mutated in place, so the formatted text updates. type: "conjunction" gives “and” lists; use "disjunction" for “or”. The empty state is handled in the template.
Compare the initial and interacted states


Copy the example
Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.
<script setup lang="ts">
import { computed, ref } from "vue";
import { useListFormat } from "@vizejs/composable/use-list-format";
const locale = ref("en-US");
const speakers = ref(["Ada", "Grace", "Linus"]);
const options = computed(() => ({ locale: locale.value, type: "conjunction" as const }));
const { formatted } = useListFormat(speakers, options);
const next = ["Margaret", "Barbara", "Alan"];
function addSpeaker() {
const name = next[speakers.value.length - 3];
if (name) speakers.value = [...speakers.value, name];
}
function removeSpeaker() {
speakers.value = speakers.value.slice(0, -1);
}
</script>
<template>
<div class="composable-example">
<p>Announce the speakers in a sentence that reads naturally in each language.</p>
<label>
Reader locale
<select v-model="locale">
<option value="en-US">English (United States)</option>
<option value="de-DE">German (Germany)</option>
<option value="ja-JP">Japanese (Japan)</option>
</select>
</label>
<div class="example-actions">
<button type="button" :disabled="speakers.length >= 6" @click="addSpeaker">
Add speaker
</button>
<button type="button" :disabled="speakers.length === 0" @click="removeSpeaker">
Remove speaker
</button>
</div>
<output aria-live="polite">{{ speakers.length > 0 ? formatted : "No speakers yet." }}</output>
</div>
</template>
Runtime contract
| Utility | Category | Stability | SSR | Hydration | Cleanup | Targets | Host globals | Uses |
|---|---|---|---|---|---|---|---|---|
useListFormat |
i18n | experimental | deterministic-fallback | caller-managed | none | web, server, worker, native, desktop, terminal | Intl, window |
useLocale |
API
useListFormat
Join strings into a locale-aware list with Intl.ListFormat ("a, b, and c", "a、b、c", "a, b or c"). Follows reactive items and options; formatters are cached per locale and option set through useLocale. Invalid options surface as the platform's RangeError. No listeners or timers are created.
function useListFormat( items: MaybeRefOrGetter<readonly string[]>, options: MaybeRefOrGetter<UseListFormatOptions> = {}, ): ListFormatControls
const { formatted } = useListFormat(names, { locale: "en", type: "disjunction" });
Types
UseListFormatOptions
Options for useListFormat.
| Member | Type | Description |
|---|---|---|
locale? |
string | Intl.Locale |
Locale used for formatting. Pass it explicitly for hydration-stable server rendering. |
ListFormatControls
Reactive list formatting returned by useListFormat.
| Member | Type | Description |
|---|---|---|
locale |
ComputedRef<string> |
Canonical locale in use. |
formatter |
ComputedRef<Intl.ListFormat> |
Cached formatter for the current locale and options. |
formatted |
ComputedRef<string> |
Formatted list, for example "apples, pears, and plums". |
format |
(items: Iterable<string>) => string |
Format any list with the current formatter. |
formatToParts |
( items: Iterable<string>, ) => { type: "element" | "literal"; value: string }[] |
Format any list into element and literal parts (for rich rendering). |