This document explains the formatting rules for a Google Sheet that manages error content.
Quick Start with Template
Copy the pre-configured template to get a sheet with the correct column structure and sample data.
TIP
After copying, edit the data and run huh pull.
Sheet Column Structure
The first row must be a header row, using the following column names:
| Column Name | Required | Description |
|---|---|---|
trackId | Yes | Unique ID identifying the error (e.g., ERR_LOGIN_FAILED) |
type | Yes | Error display type: TOAST, MODAL, PAGE, or custom type |
message | Yes | Error message shown to the user |
title | Error title (used for modal, page) | |
image | Image URL (used for page) | |
severity | Severity level: INFO, WARNING, ERROR, CRITICAL, or custom severity | |
actionLabel | Action button text | |
actionType | Action kind: REDIRECT, RETRY, BACK, DISMISS, or custom action | |
actionTarget | Action target URL (required for REDIRECT) |
Error Types (type)
Built-in types:
| Type | Use Case | Recommended Fields |
|---|---|---|
TOAST | Simple notification message | Use message only. Warning if title/image are used |
MODAL | Popup-style error notice | message + title + action |
PAGE | Full-screen error page | message + title + image + action (warning if no action) |
TIP
Custom types (BANNER, SNACKBAR, etc.) can also be used freely. Even if entered in lowercase, they are automatically converted to uppercase.
Action Types (actionType)
Built-in action types:
| Type | Behavior | Requires target |
|---|---|---|
REDIRECT | Navigate to specified URL | Yes (actionTarget with URL) |
RETRY | Close error + execute retry callback | No |
BACK | Browser back (history.back()) | No |
DISMISS | Close error UI | No |
TIP
Custom action types (OPEN_CHAT, SHARE, etc.) can also be used. Handle them via the HuhProvider's onCustomAction callback.
Template Variables
You can use template variables in the format in messages, titles, action labels, and action targets. Variables are passed at runtime when calling huh.
Message example: {{userName}}, your request could not be processed.
Target example: /user/{{userId}}/settingsExamples
| trackId | type | message | title | image | severity | actionLabel | actionType | actionTarget |
|---|---|---|---|---|---|---|---|---|
| ERR_NETWORK | TOAST | Please check your network connection | WARNING | |||||
| ERR_AUTH | MODAL | Authentication is required | Login Required | ERROR | Login | REDIRECT | /login | |
| ERR_TIMEOUT | MODAL | The request has timed out | Timeout | ERROR | Try Again | RETRY | ||
| ERR_FORBIDDEN | PAGE | does not have access permission | Access Denied | /img/403.png | CRITICAL | Go Back | BACK | |
| ERR_NOT_FOUND | PAGE | Page not found | 404 | /img/404.png | INFO | Go Home | REDIRECT | / |
Rules Summary
- Rows with an empty
trackIdare ignored trackId,type, andmessageare requiredtypemust not be empty (built-in:TOAST,MODAL,PAGE; custom types also allowed)actionTargetis required whenactionTypeisREDIRECT- Lowercase input is automatically converted to uppercase by the CLI
actionLabelandactionTypemust be provided together (both present or both absent)
Google Sheet Access Configuration
To access the sheet from the CLI, one of the following authentication methods is required:
Method 1: API Key (for public sheets)
- Create a project in the Google Cloud Console
- Enable the Google Sheets API
- Generate an API Key
- Set the sheet to "Anyone with the link can view"
- Set the environment variable:
GOOGLE_API_KEY=your-api-key
Method 2: Service Account (for private sheets)
- Create a service account in the Google Cloud Console
- Download the JSON key file
- Grant "Viewer" permission to the service account email in the sheet
- Specify the credentials path in the config file:
{
"source": {
"type": "google-sheets",
"sheetId": "YOUR_SHEET_ID",
"credentials": "./service-account.json"
},
"output": "./src/huh.json"
}