Server-Driven UI Client Design
Use a component registry and design systems and tokens to simplify client logic
In server-driven UI (SDUI), the client's goal is to handle pixels, not data. The client should simply take what the API provides and render it in the proper location.
When adopting SDUI incrementally, you usually start with basic UI elements like text and images. As you shift more logic, such as component layouts, to the server, clients can have a set of UI component types mapped to their specific platform. This allows clients to render content tailored to their platform.
Component registry
Once your API has more control over which components apps should render, you need to define the mapping from GraphQL types to the UI equivalent components (for example, in React, SwiftUI, Jetpack, etc.). This mapping is called a component registry.
The snippet below includes a simplified version of a React component registry:
1const {data} = useQuery(FeaturedProductsCollection);
2
3// Maps GraphQL __typename to UI component
4const TYPE_COMPONENTS = {
5 ProductList: ListComponent,
6 ProductCarousel: CarouselComponent,
7 ProductError: ErrorComponent
8};
9
10const component = TYPE_COMPONENTS[data.featuredProducts.__typename];
11if (!component) {
12 throw new Error('Unknown Type Returned!');
13}
14
15renderComponent(component, data);
This snippet uses the registry (TYPE_COMPONENTS
) to dynamically render the appropriate UI component based on the __typename
of the API response. The request generating that response could be based on client inputs, including headers, user information, or even information from previous server responses.
Design systems and tokens
Client libraries may also implement design systems. While the choice of what grid format to use or spacing should be kept on the client side, the API should control other choices, like whether a badge should be red or green based on user state or data.
Rather than returning hex codes in a request for something like badge color, it's best to use a design system that operates on tokens so you can change the business logic behind color choices more easily.
A client consuming such a response doesn't need to know what each badge is for or its color; it only needs to render the list of badges.
1{
2 "badges": [
3 {
4 "text": "Loyalty members get a discount",
5 "theme": "brand-color:primary"
6 },
7 {
8 "text": "Inventory is low, buy now!",
9 "theme": "brand-color:warning"
10 }
11 ]
12}