• English
  • Without React

    Use Aora Bot from plain HTML or any framework through the <aora-bot> custom element, or call the engine directly when you want no element at all.

    From a CDN

    One script tag is the whole setup. The file bundles the engine and registers <aora-bot> when it loads, so there is no build step.

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>Aora Bot</title>
        <script type="module" src="https://cdn.jsdelivr.net/npm/@aora-bot/element"></script>
      </head>
      <body>
        <aora-bot character="mochi" state="happy" size="120"></aora-bot>
      </body>
    </html>

    Pin a version in the URL, for example @aora-bot/element@0.1.3, so a later release cannot change a page you have already shipped.

    Not yet available in mainland China

    jsDelivr is unreliable in mainland China, so a page that loads the element from the CDN may fail to load there. Installing from npm and bundling it with your project is not affected. Access for users in mainland China is planned.

    Install

    With a bundler, install the package and register the element once, early in your entry file:

    pnpm add @aora-bot/element
    import { defineAoraBot } from '@aora-bot/element';
    
    defineAoraBot();

    defineAoraBot(tagName = 'aora-bot') returns the element class and is safe to call more than once. Importing the package never touches the DOM, so it is safe in a server render or a build step, where defineAoraBot registers nothing. @aora-bot/engine comes along as a dependency. To serve the bundled file from your own host, import @aora-bot/element/cdn.

    The package is ESM-only, like the others.

    Attributes

    Every attribute is optional. A value the engine does not know falls back to the default, or to the cast member's choice, and never throws.

    AttributeWhat it controls
    characterA cast id such as mochi; sets shape, color, face and nose
    shapeWhich character to draw, mochi by default
    colorOne hue of the palette, black by default
    facecute (default), eyes or line, see Faces
    noseA nose id for the line face, or none; derived from seed by default
    stateWhat it is doing, one of the animation states, idle by default
    style-idThe style series: vector (default), pixel or kaomoji
    variantA variant of that style, such as outline or dot
    style-optionsA JSON object of that style's parameters, such as {"paperOffset":12}
    seedAny string; two characters with different seeds do not blink in unison
    sizeA CSS length, or a number of pixels; 28px by default
    eye-colorA CSS colour for the eye cut-outs
    badge-colorA CSS colour for the badge shown in the notifying state
    eye-scaleA positive multiplier on eye size, 1 by default
    line-weightA multiplier from 0.8 to 1.25 on the stroke weight, 1 by default
    reduced-motionBoolean. Draw one still frame instead of animating; follows the OS setting when absent
    pausedBoolean. Hold the current frame
    emphasisBoolean. Enlarge and converge the eyes
    anticsBoolean. Hop or spin now and then while idle
    auto-pauseBoolean. Stop while the page is hidden or the character is scrolled out of view

    The style series is style-id because style is already the inline CSS attribute. Changing an attribute updates the running character. Only seed, reduced-motion and auto-pause are read once, so changing one of them builds a new character.

    style-options takes the parameters of the chosen style, which are listed on the style pages (vector, pixel, kaomoji). Write them as a JSON object in a single-quoted attribute; a value that is not a JSON object is ignored, and removing the attribute restores the defaults.

    <aora-bot shape="mochi" color="blue" variant="paper" style-options='{"paperOffset":12}'></aora-bot>

    The element is role="img" and carries an aria-label with the cast member's name, in Chinese when the nearest lang is zh. Set your own aria-label or role and they are left alone.

    The character is drawn in a shadow root, so page CSS cannot reach inside it. The host is display: inline-block; size it with size, or with your own width and height. The ink follows the page's color-scheme, and --aora-bg-base on any ancestor sets the colour behind the eye cut-outs, as described in Theming.

    Methods

    MemberWhat it does
    spin(turns?)Spin the body turns full revolutions, one by default
    bounce(strength?)Hop; strength scales the height, 1 by default
    burst(count?)Throw confetti
    pause(), resume()Hold or release the current frame
    controllerThe engine's CharacterController, or null while not in a document

    The methods do nothing while the element is not in a document.

    Changing state from JavaScript

    Every attribute is also a property in camel case, so el.state = 'happy' is the same as el.setAttribute('state', 'happy'). The running character is updated in place and its springs carry over, which is what makes a state change look like a reaction rather than a restart.

    <aora-bot id="bot" character="luna" size="120"></aora-bot>
    <button id="ask">Ask</button>
    
    <script type="module">
      const bot = document.querySelector('#bot');
    
      document.querySelector('#ask').addEventListener('click', async () => {
        bot.state = 'thinking';
        await new Promise((resolve) => setTimeout(resolve, 1500));
        bot.state = 'happy';
        bot.bounce();
      });
    </script>

    For options with no attribute, such as followTarget or hud, call update on the controller:

    bot.controller.update({ hud: { kind: 'progress', value: 0.4 } });

    Without the element

    If you would rather not register a custom element, @aora-bot/engine has the same character as a function. @aora-bot/element is a thin layer over it.

    import { createCharacter } from '@aora-bot/engine';
    
    const host = document.querySelector('#avatar')!;
    const character = createCharacter(host, { shape: 'mochi', state: 'happy', seed: 'mochi:blue' });
    
    character.update({ state: 'thinking' });
    character.spin(2);
    character.destroy();

    createCharacter mounts one SVG into the host and returns a controller; call destroy() when you remove the host. The ink is the surrounding text colour until you set the --aora-fg custom property on the host, or pass ink. See the engine README for the rest.

    Next

    • Theming — the variables that draw a character
    • Cast — every named character
    • States — everything a character can be doing