Agriculture Design System
Beta
Design System for the Export Service

Loading, empty and error states

When loading data in an application, it is important to consider and design for loading, empty, and error states. These states will help set user expectations and prevent them from assuming that the interface is unresponsive.

View in FigmaView in Storybook

Loading state

The loading state provides feedback to users that data is being loaded.

Loading states can reduce uncertainty for the user by explaining what is happening and preparing them for what is coming up next.

Skeleton components can be used as visual placeholders for information that is still loading - e.g. cells inside of a table.

Table loading state example

Below is an example of a Table in a loading state.

Open in Playroom, opens in a new tab
<TableWrapper>
	<Table tableLayout="fixed">
		<TableHead>
			<TableRow>
				<TableHeader width="6rem" scope="col">
					ID
				</TableHeader>
				<TableHeader scope="col">Name</TableHeader>
				<TableHeader scope="col">Email</TableHeader>
			</TableRow>
		</TableHead>
		<TableBody>
			{Array.from(Array(5)).map((_, idx) => (
				<TableRow key={idx}>
					<TableCell>
						<SkeletonText />
						<VisuallyHidden>Loading</VisuallyHidden>
					</TableCell>
					<TableCell>
						<SkeletonText />
						<VisuallyHidden>Loading</VisuallyHidden>
					</TableCell>
					<TableCell>
						<SkeletonText />
						<VisuallyHidden>Loading</VisuallyHidden>
					</TableCell>
				</TableRow>
			))}
		</TableBody>
	</Table>
</TableWrapper>

Cards loading state example

Below is an example of a list of Cards in a loading state.

<Columns as="ul" cols={{ xs: 2 }}>
	{Array.from(Array(2).keys()).map((i) => (
		<Card key={i} as="li" shadow>
			<CardInner>
				<Stack gap={1}>
					<SkeletonHeading type="h3" width="50%" />
					<SkeletonText fontSize="sm" width="25%" />
					<VisuallyHidden>Loading</VisuallyHidden>
				</Stack>
			</CardInner>
		</Card>
	))}
</Columns>

Error state

The error state provides feedback to users that an error has occurred while loading the data.

When creating an error message:

  • Be specific in describing the error
  • Distil technical jargon into more simple and conversational language where possible
  • Describe how and when the error can be resolved
  • Don’t blame the user for the error
  • Include the error code in the message if possible. It may be helpful is a user accesses human-led support.

If applicable, use a Button component to provide the user with an option to retrieve the data again.

Section level error state

Below is an example of an error that occured at the section level.

<Stack gap={2} alignItems="flex-start">
	<Stack gap={1}>
		<AlertFilledIcon color="error" size="lg" />
		<Heading type="h2" fontSize="lg">
			Failed to load
		</Heading>
		<Text>There was an error loading the data. Click retry to try again.</Text>
	</Stack>
	<Button>Retry</Button>
</Stack>

Component level error state

Below is an example of an error that occured at the component level.

<Flex gap={0.75}>
	<AlertFilledIcon color="error" />
	<Stack gap={1} alignItems="flex-start">
		<Stack gap={0.5}>
			<Text fontWeight="bold">Failed to load</Text>
			<Text>
				There was an error loading the data. Click retry to try again.
			</Text>
		</Stack>

		<Button variant="text">Retry</Button>
	</Stack>
</Flex>

Page level error state

For errors which occur at the page level, see the Error page template.

Empty state

The empty state is displayed when data has loaded succesfully, but there is nothing available to show to the user.

This state could potentially be a result of either:

  • a new user vists a service for the first time and needs to create data
  • a user applies a number of filters or settings which do return any results

Depending on what the cause the empty state is, provide clear messaging and a helpful action to get rid of the empty state via a Button component.

Section level empty state examples

Below is an example of two different empty states at the section level.

<Stack gap={2} alignItems="flex-start">
	<Stack gap={1}>
		<FactoryIcon size="lg" color="muted" />
		<Heading type="h2" fontSize="lg">
			Add an establishment
		</Heading>
		<Text>You haven’t added any establishments yet.</Text>
	</Stack>
	<Button>Add establishment</Button>
</Stack>
<Stack gap={2} alignItems="flex-start">
	<Stack gap={1}>
		<HelpIcon size="lg" color="muted" />
		<Heading type="h2" fontSize="lg">
			No results found
		</Heading>
		<Text>Try adjusting your filter options.</Text>
	</Stack>
	<Button>Clear filters</Button>
</Stack>

Component level empty state example

Below is an example of an empty state at the component level.

<Flex gap={0.75}>
	<HelpIcon color="muted" />
	<Stack gap={1} alignItems="flex-start">
		<Stack gap={0.5}>
			<Text fontWeight="bold">No results found</Text>
			<Text>Try adjusting your filter options.</Text>
		</Stack>
		<Button variant="text">Clear filters</Button>
	</Stack>
</Flex>
  • Button A button communicates an action to a user and indicates what will happen next.
  • Heading Headings are a typographic component that create semantic structure, allow users to scan content by creating relative visual prominence and support search engine optimisation.
  • Icon The Agriculture Design System supports the use of universal system icons. The icon component is used to apply our set of universal icons to more complex components of the system.
  • Skeleton Skeletons are visual placeholders for information while data is still loading.
  • Text A primitive typographic component for constrained text styles.