Skip to content
Version: XState v4

Other state attributes

States can have various other attributes, most of which are useful for narrower cases.

State tags​

State nodes can have tags, a list of strings that help describe the state node. Tags can be useful when categorizing different state nodes. For example, you can signify which state nodes represent “loading data” using a "loading" tag and determine if a state contains those tagged state nodes with state.hasTag(tag):

import { createMachine, interpret } from 'xstate';

const machine = createMachine({
initial: 'idle',
states: {
idle: {
on: {
FETCH: 'loadingUser',
},
},
loadingUser: {
tags: ['loading'],
},
loadingFriends: {
tags: ['loading'],
},
editing: {},
},
});

const actor = interpret(machine).start();

actor.state.hasTag('loading'); // false

actor.send('FETCH');

actor.state.hasTag('loading'); // true

Using tags can help you write more concise code. Instead of matching each actor individually:

import { createMachine, interpret } from 'xstate';

const machine = createMachine({
initial: 'idle',
states: {
idle: {
on: {
FETCH: 'loadingUser',
},
},
loadingUser: {
tags: ['loading'],
},
loadingFriends: {
tags: ['loading'],
},
editing: {},
},
});

const actor = interpret(machine).start();

const isLoading =
actor.state.matches('loadingUser') || actor.state.matches('loadingFriends');

You can group the actors by tag:

import { createMachine, interpret } from 'xstate';

const machine = createMachine({
initial: 'idle',
states: {
idle: {
on: {
FETCH: 'loadingUser',
},
},
loadingUser: {
tags: ['loading'],
},
loadingFriends: {
tags: ['loading'],
},
editing: {},
},
});

const actor = interpret(machine).start();

const isLoading = actor.state.hasTag('loading');

Using tags in Stately Studio​

You can add tags to states and events in Stately Studio.

First, select the state or event you want to tag.

On the canvas​

  1. Use the plus icon button to open the edit menu.
  2. Choose Tag from the menu to add a tag block.
  3. Write your tag’s name in the tag’s text input.
  4. Use the plus icon button alongside your recent tag to add more tags.

Using the event details panel​

  1. Open the state or event Details panel from the right tool menu.
  2. Use the + Tag button to add a tag block.
  3. Write your tag’s name in the tag’s text input.
  4. Use the plus icon button alongside your recent tag to add more tags.

Defining tags​

  • Tags can be specified via an array, as tag: ['tag1', 'tag2'], or by a single string: tag: 'tag1'.
  • Tags can be made type-safe in TypeScript by using typegen.

State meta​

You can attach arbitrary data to any state by specifying it as meta on the state node:

import { createMachine, interpret } from 'xstate';

const fetchMachine = createMachine({
initial: 'pending',
states: {
pending: {
on: {
UNKNOWN_ERROR: 'errored',
},
after: {
5000: 'timedOut',
},
},
errored: {
meta: {
error: 'An unknown error occurred',
},
},
timedOut: {
meta: {
error: 'Timeout error!',
},
},
},
});

You can store anything in the meta attribute; XState doesn’t monitor it or do anything with its contents.

The current state of the machine collects the meta data of all of the state nodes, represented by the state value, and places them on an object where:

  • The keys are the state node IDs
  • The values are the state node meta values

For instance, if the machine above is in the timedOut state, the meta will be an object with the following shape:

{
timedOut: {
alert: 'Timeout error!'
},
}

State descriptions​

You can add descriptive text to states with the description attribute.

This text is used by the Visualizer and the Studio Editor to make the diagrams more descriptive.

import { createMachine } from 'xstate';

const machine = createMachine({
initial: 'pending',
description: `A machine that waits for something to happen, then completes`,
states: {
pending: {
on: {
FINISHED: 'complete',
},
description: `Waiting...`,
},
complete: {
description: `Done!`,
},
},
});