Vivid API

Vivid-API v6.0.0 Migration Guide

This document provides descriptions of the breaking changes in this release and instructions on how to prepare for them.

See the AI-Assisted Migration guide for how to automate this migration with codemods and an AI agent.

Icon Attribute Removal

The Change

The deprecated icon attribute has been completely removed from all components. You must now use the icon slot to provide icons to components.

Previously, you could set an icon by name using the icon attribute:

<vwc-button label="Send" icon="send-line"></vwc-button>

In V6, you must use the icon slot instead:

<vwc-button label="Send">
<vwc-icon slot="icon" name="send-line"></vwc-icon>
</vwc-button>
  • Accordion Item
  • Alert
  • Avatar
  • Badge
  • Banner
  • Button
  • Card
  • Combobox
  • Dialog
  • Empty State
  • Fab
  • Menu
  • Menu Item
  • Nav
  • Nav Disclosure
  • Nav Item
  • Note
  • Option
  • Searchable Select
  • Select
  • Split Button
  • Status
  • Tab
  • Tabs
  • Tag
  • Text Field
  • Tree Item

How to Get Ready?

Replace all usages of the icon attribute with a slotted <vwc-icon> element.

Web Components

<vwc-button label="Send" icon="send-line"></vwc-button>
<vwc-button label="Send">
<vwc-icon slot="icon" name="send-line"></vwc-icon>
</vwc-button>

Vue

<VButton label="Send" icon="send-line" />
<VButton label="Send">
<template #icon><VIcon name="send-line" /></template>
</VButton>

Icon Component Now Uses Icon Font

The Change

The Icon component no longer fetches individual SVG files from the CDN. It now renders icons using an icon font, which is loaded automatically when you include the Vivid theme stylesheet.

The icon font @font-face declarations (VividApiLineIcons and VividApiSolidIcons) are now included in the theme CSS (theme.scss). This means icons load faster and no longer require individual network requests per icon.

Key behavior changes:

  • Icons no longer show an aria-busy loading state.
  • The Icon component only supports mono-color icons. Multi-color brand icons must use the new Brand component.
  • If you relied on the internal _svg or iconLoaded properties, they no longer exist on the Icon component.

How to Get Ready?

For most users, this change is transparent. Icons continue to work with the same name attribute.

However, you should verify the following:

  1. Your application includes the Vivid theme stylesheet. The icon font is loaded via @font-face declarations in the theme CSS. If you are already using theme.scss (or the compiled CSS), no additional setup is needed.

  2. Your CSP (Content Security Policy) allows font loading from the icons CDN. The icon font is loaded from https://icons.api.vivid.vonage.com. Ensure your font-src directive includes this domain:

font-src 'self' https://icons.api.vivid.vonage.com;
  1. You are not relying on aria-busy on icons. The Icon component no longer sets aria-busy while loading since icon font glyphs render immediately.

  2. Brand and flag icons are migrated. Multi-color brand icons and flag icons can no longer be displayed using <vwc-icon>. See the Brand Icons and Flag Icons sections below.

Brand Icons

The Change

Multi-color brand icons (e.g., brand-android-color, brand-slack-color) are no longer supported by the Icon component because the icon font only renders mono-color glyphs.

A new <vwc-brand> component has been introduced to display multi-color brand icons. It fetches and renders the SVG directly, preserving the full-color appearance.

<!-- Before -->
<vwc-icon name="brand-android-color"></vwc-icon>
<vwc-icon name="brand-github"></vwc-icon>
<!-- After -->
<vwc-brand name="android"></vwc-brand>
<vwc-brand name="github" variant="mono"></vwc-brand>

The Brand component supports a variant attribute:

  • color (default) — renders the full-color brand icon
  • mono — renders the monochrome version

How to Get Ready?

Replace all brand icon usages with the Brand component.

Web Components

<vwc-icon name="brand-slack-color"></vwc-icon>
<vwc-brand name="slack"></vwc-brand>

When used inside other components via the icon attribute (now removed), combine both migrations:

<vwc-button label="Login" icon="brand-facebook-color"></vwc-button>
<vwc-button label="Login">
<vwc-brand slot="icon" name="facebook"></vwc-brand>
</vwc-button>

Vue

<VIcon name="brand-slack-color" />
<VBrand name="slack" />

Remember to update your imports:

import { VIcon } from '@vonage/vivid-api-vue';
import { VBrand } from '@vonage/vivid-api-vue';

Registration (Web Components)

Register the Brand component in your application:

import { registerBrand } from '@vonage/vivid-api';
registerBrand('vwc');

Flag Icons

The Change

Flag icons (e.g., flag-poland, flag-united-kingdom) displayed via <vwc-icon> should be migrated to the dedicated <vwc-flag> component. The Flag component uses a code attribute with the ISO 3166-1 alpha-2 country code instead of the icon name.

<!-- Before -->
<vwc-icon name="flag-poland"></vwc-icon>
<vwc-icon name="flag-united-kingdom"></vwc-icon>
<!-- After -->
<vwc-flag code="PL"></vwc-flag>
<vwc-flag code="UK"></vwc-flag>

How to Get Ready?

Replace all flag icon usages with the Flag component, mapping the flag name to its country code.

Web Components

<vwc-icon name="flag-germany" size="2"></vwc-icon>
<vwc-flag code="DE" size="2"></vwc-flag>

Vue

<VIcon name="flag-france" />
<VFlag code="FR" />

Remember to update your imports:

import { VIcon } from '@vonage/vivid-api-vue';
import { VFlag } from '@vonage/vivid-api-vue';

Registration (Web Components)

Register the Flag component in your application:

import { registerFlag } from '@vonage/vivid-api';
registerFlag('vwc');

The codemod handles the name-to-code mapping automatically. If a flag name cannot be resolved, it adds a /* TODO */ comment for manual review.

Button, Fab, and Split Button - Click Behavior

The Change

<vwc-button>, <vwc-fab>, and <vwc-split-button> no longer cancel the click event’s default action when the button is enabled. Previously, these components called event.preventDefault() on every click, regardless of the disabled or pending state. This broke integrations that rely on the default click action, f.e. vue-router navigation:

<!-- Before: navigation was never triggered because e.defaultPrevented was always true -->
<NuxtLink to="/foo" custom v-slot="{ navigate }">
<VButton label="Go" appearance="filled" @click="(e) => navigate(e)" />
</NuxtLink>

In V6, event.preventDefault() is only called when the button is disabled or pending. On enabled buttons, the click event’s default action now proceeds as expected.

How to Get Ready?

If you worked around the previous behavior (for example, by manually calling navigate(event) because event.defaultPrevented was always true), you can remove that workaround. Review any click handlers on Button, Fab, or Split Button that inspected event.defaultPrevented, since it will now correctly reflect false for enabled buttons.