say-my-name

Hi, I'm Jailson

A tiny web component that shows people how to say your name — your own recording, a dictionary-style phonetic spelling, and speech synthesis when there is no recording. One tag. No account, no backend, nothing phoning home.

Record or upload your name → Source on GitHub

Install

From a CDN, no build step:

<script type="module"
  src="https://cdn.jsdelivr.net/npm/@jailson/say-my-name@0"></script>

<say-my-name audio="/audio/my-name.opus" respell="zhah-EEL-sown">
  Jailson
</say-my-name>

Or as a package:

npm install @jailson/say-my-name
import '@jailson/say-my-name';

How it looks

Just a play button

Ask Jailson about it.

<say-my-name lang="pt-BR">Jailson</say-my-name>

With a respelling, inline

Jailson

<say-my-name respell="zhah-EEL-sown" lang="pt-BR">
  Jailson
</say-my-name>

Dictionary style, with IPA

Jailson

<say-my-name respell="zhah-EEL-sown" ipa="ʒaˈiwsõ"
             lang="pt-BR" display="ruby">
  Jailson
</say-my-name>

More than one right answer

Jailson

A name can have a native pronunciation and the one you answer to locally. Both are correct. Most tools make you pick one; this one doesn't.

<say-my-name display="ruby">
  Jailson
  <script type="application/json">
    [{"label": "Portuguese", "lang": "pt-BR",
      "respell": "zhah-EEL-sown", "ipa": "ʒaˈiwsõ"},
     {"label": "How I'm called here", "lang": "en-CA",
      "respell": "JAY-ill-sun"}]
  </script>
</say-my-name>

About the voice

The examples above use live browser synthesis, because a demo page has no audio of your voice. On your own site you'd supply a file. Three things are worth knowing about relying on the browser instead:

So live synthesis is the weakest of the options, and the component is careful about it: a synthesized button draws a dashed sound wave and says so in its accessible label, and if the browser has no voice for your language it renders no button at all rather than mispronouncing you confidently.

A recording is the most faithful answer — but it isn't the only respectable one. A clean, isolated sample of your voice on a public page is exactly what voice-cloning models want, and declining to publish one is reasonable. Generating a clip from a text-to-speech tool, marking it synthetic, and shipping that is a perfectly good outcome. What matters is that a listener is never misled about which one they are hearing.

Record or upload your name →

Attributes

AttributeDefaultWhat it does
audio URL of your recording. Loaded only when someone presses play.
respell Dictionary-style respelling for humans, e.g. zhah-EEL-sown.
ipa IPA, with or without slashes. Hidden from screen readers, which read the symbols as gibberish.
lang BCP 47 tag. Picks the speech voice; the button hides if no voice matches.
ttsfallback off · fallback (only when there's no recording) · on (both, as separate buttons).
tts-textthe name What the synthesizer is actually given. Set it when the spelled name comes out wrong.
syntheticabsent Marks an audio file as a synthesized voice, so its button is labelled like live synthesis.
voicebest match Preferred voice name, e.g. Luciana.
rate0.9 Speech rate. Names land better slightly slower than default.
displayinline none · inline · ruby (respelling above the name, IPA below) · tooltip.
showboth both · respell · ipa. Which written forms appear at all.
nameelement text Only needed if the element has no text of its own.

Styling

Custom properties, or ::part() for full control:

say-my-name {
  --smn-color: #6b46c1;
  --smn-phonetic-color: #666;
  --smn-phonetic-size: 0.8em;
  --smn-button-size: 1em;
  --smn-focus: 2px solid #6b46c1;
}
say-my-name::part(button) { border-radius: 999px; }
say-my-name::part(ipa) { font-family: 'Doulos SIL', serif; }

Accessibility

Frameworks

It's a custom element, so it works anywhere HTML does. React 19+ passes props to custom elements natively. Vue needs compilerOptions.isCustomElement. Svelte and Astro need nothing.