RichLabel.Maui ๐
A powerful, flexible, and lightweight .NET MAUI control for rendering rich text from a simple JSON structure. It provides seamless, extensible support for interactive tap gestures, making it easy to handle links, phone numbers, emails, or trigger custom actions within your app.
Preview

Features โจ
- JSON-Driven Text โ Render complex, formatted labels using a clean, well-structured JSON schema.
- Rich Styling โ Native support for custom font families, sizes, bold, italic, underline, text colors, and background colors per text segment.
- Advanced Layouts โ Render standard paragraphs, custom bulleted lists, and auto-numbered sequences.
- Extensible Tap Gestures โ Pass custom action types and data payloads through JSON to trigger native actions (phone calls, custom alerts, view navigation, etc.).
- Cross-Platform Alignment โ Supports Start, Center, End, and Justified text alignment.
- Safe Formatting & Scaling โ Built-in validation prevents crashes from invalid formatting input, with automatic font scaling for tablets.
Installation ๐ฆ
Add the NuGet package to your .NET MAUI project:
dotnet add package RichLabel.Maui
Quick Start ๐
1. Define your JSON data
Your backend or local storage can provide a JSON structure describing each line and text segment:
{
"lines": [
{
"type": "Normal",
"alignment": "Center",
"spans": [
{
"fontFamily": "OpenSansSemibold",
"fontSize": 20,
"text": "Center title, font OpenSansSemibold, size 20"
}
]
},
{
"type": "Normal",
"spans": [
{
"color": "#ff2c2c",
"text": "Red colored text"
}
]
},
{
"type": "Normal",
"spans": [
{
"bold": true,
"text": "This is bold text"
}
]
},
{
"type": "Normal",
"spans": [
{
"underline": true,
"text": "This is underlined text"
}
]
},
{
"type": "Normal",
"alignment": "End",
"spans": [
{
"bold": true,
"text": "End-aligned text"
}
]
},
{
"type": "Normal",
"spans": [
{
"bold": true,
"text": "Bullet list"
}
]
},
{
"type": "Bullet",
"bulletChar": "โข",
"indentLevel": 1,
"spans": [
{ "text": "Option A" }
]
},
{
"type": "Bullet",
"bulletChar": "โข",
"indentLevel": 1,
"spans": [
{ "text": "Option B" }
]
},
{
"type": "Normal",
"spans": [
{
"bold": true,
"text": "Auto-numbered list"
}
]
},
{
"type": "Numbered",
"indentLevel": 1,
"spans": [
{ "text": "Option A" }
]
},
{
"type": "Numbered",
"indentLevel": 1,
"spans": [
{ "text": "Option B" }
]
},
{
"type": "Normal",
"spans": [
{ "text": "Tap here -> " },
{
"fontFamily": "RegularFont",
"text": "1-888-555-88888",
"bold": true,
"underline": true,
"color": "#FF8100",
"actionType": "phone",
"actionValue": "188855588888"
}
]
},
{
"type": "Normal",
"spans": [
{
"fontFamily": "RegularFont",
"text": "Tap me for a message",
"bold": true,
"underline": true,
"color": "#0000FF",
"actionType": "text",
"actionValue": "Thanks for tapping!"
}
]
},
{
"type": "Normal",
"alignment": "Justify",
"spans": [
{
"text": "This is justified text. Note: justified alignment is currently supported on Android only. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus."
}
]
}
]
}
2. Deserialize your JSON data
Use your preferred JSON library to deserialize the data into a RichTextDocument object:
RichTextDocument richDocument = JsonConvert.DeserializeObject<RichTextDocument>(jsonData);
3. Add the control to your XAML
Register the namespace and drop the control into your layout:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Sample.RichLabel.Maui.MainPage"
xmlns:viewModels="clr-namespace:Sample.RichLabel.Maui.ViewModels"
xmlns:richLabel="clr-namespace:RichLabel.Maui.Control;assembly=RichLabel.Maui">
<ScrollView>
<Grid RowDefinitions="*" ColumnDefinitions="*">
<!-- Set IsResponsiveFontSize="True" to enable automatic font scaling on tablets -->
<richLabel:RichLabel
Grid.Row="0"
Document="{Binding RichDocument}"
Margin="{OnIdiom Phone=10, Tablet=15, Default=15}"
IsResponsiveFontSize="True" />
</Grid>
</ScrollView>
</ContentPage>
Handling Actions ๐ ๏ธ
For custom app workflows, register a RichActionHandler in your App.xaml.cs:
using RichLabel.Maui.Handlers;
namespace Sample.RichLabel.Maui
{
public partial class App : Application
{
public App()
{
InitializeComponent();
InitActionTouchHandler();
}
public void InitActionTouchHandler()
{
RichActionHandler.Register("phone", async value =>
{
await Shell.Current.DisplayAlert("Phone Data", $"Parameter value: {value}", "Close");
});
RichActionHandler.Register("text", async value =>
{
await Shell.Current.DisplayAlert("Text Data", $"Parameter value: {value}", "Close");
});
}
protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new AppShell());
}
}
}
Each actionType in your JSON (e.g. "phone", "text") maps to a handler registered here, letting you define exactly what happens when a user taps that segment.
Contributing ๐ค
Contributions, issues, and feature requests are welcome! Feel free to check the issues page or open a pull request.
Support the Project โ
If this component saves you development time or streamlines your dynamic text workflows, feel free to drop a star on the repository! โญ
- NuGet URL: RichLabel.Maui Packages
- Project Support: Support on Ko-fi