# Template

A Template is the **content and copy layer** for the Gamopanda end-user widget. It controls every piece of text and imagery that an end user sees — from the logged-in/logged-out titles down to the "Copied!" confirmation when they tap a coupon code. You create one Template per account and it is served to every end user and guest visitor who views the widget.

:::tip
All text fields in a Template are **localisable**. Supply a `languageCode` query parameter when fetching the template to receive translated strings. This makes it straightforward to serve a fully localised widget with a single API call.
:::

---

## How it works

1. **Create a template** — set the core `name` and `description`, then configure every EUD (end-user display) field with your brand copy and icons.
2. **Widget loads** — when a user opens the Gamopanda widget (logged in or not), it fetches the template to render titles, section headings, button labels, and empty-state messages.
3. **Logged-in vs logged-out** — the widget automatically shows different copy depending on whether the user has an active session. `loggedInTitle` / `loggedInSubTitle` are shown to authenticated users; `loggedOutTitle` / `loggedOutSubTitle` plus the sign-up and login CTAs are shown to guests.
4. **Localisation** — all fields are returned in the language requested via the `languageCode` query parameter. Falls back to the default language if no translation exists.
5. **Guest access** — templates are readable by unauthenticated visitors so the widget can render even before a user logs in.

---

## Fields

### Basic information

| Field | Type | Required | Max length | Description |
|---|---|---|---|---|
| `name` | string | ✅ | 256 | Internal name for this template |
| `description` | string | ✅ | 1 024 | Internal description for this template |

---

## End-user display (EUD)

All fields below are **localisable** — they are stored per language and returned in the requested locale.

### Logged-in state

Shown when an end user has an active session.

| Field | Default | Max length | Description |
|---|---|---|---|
| `loggedInTitle` | — | 128 | Main title shown to authenticated users |
| `loggedInSubTitle` | — | 256 | Subtitle shown to authenticated users |

### Logged-out state

Shown when a visitor is not authenticated.

| Field | Default | Max length | Description |
|---|---|---|---|
| `loggedOutTitle` | — | 128 | Main title shown to guests |
| `loggedOutSubTitle` | — | 256 | Subtitle shown to guests |
| `joinNowButtonText` | `Join Now` | 32 | CTA button label for new sign-ups |
| `signupUrl` | — | — | URL (type: URL) the sign-up button points to |
| `alreadyHaveAccountText` | `Already have an account?` | 128 | Prompt text shown alongside the login button |
| `loginButtonText` | `Login` | 32 | CTA button label for returning users |
| `loginUrl` | — | — | URL (type: URL) the login button points to |

### Section headings & empty states

| Field | Default | Max length | Description |
|---|---|---|---|
| `streakSectionTitle` | `Streaks` | 32 | Heading for the streaks section in the widget |
| `noStreaksTextMessage` | `There are no streaks available at the moment. Please check back later!` | 256 | Shown when no active streaks exist |
| `challengeSectionTitle` | `Challenges` | 32 | Heading for the challenges section in the widget |
| `noChallengesTextMessage` | `There are no challenges available at the moment. Please check back later!` | 256 | Shown when no active challenges exist |
| `genericErrorMessage` | `Something went wrong. Please try again later!` | 256 | Fallback message shown when any API error occurs |

### Rewards

| Field | Default | Max length | Description |
|---|---|---|---|
| `rewardsPageTitle` | `Your Rewards` | 32 | Title of the rewards tab/page |
| `rewardsViewAllButtonText` | `View All` | 32 | Label for the "view all rewards" button |
| `noRewardsTextMessage` | `No rewards are available. Please participate in streaks and challenges to earn rewards!` | 256 | Shown when the user has no reward logs |
| `rewardRedeemedLabel` | `Redeemed` | 32 | Badge label for a redeemed reward |
| `rewardExpiredLabel` | `Expired` | 32 | Badge label for an expired reward |
| `copiedText` | `Copied!` | 32 | Confirmation text shown after a coupon code is copied to clipboard |
| `rewardIcon` | *(default reward icon)* | — | Icon displayed alongside rewards. Allowed: PNG, JPEG, JPG, GIF, SVG · Max size: 100 KB |

---

## Real-world examples

**🛍️ E-commerce — English template**

```json
{
  "name": "Main Widget Template",
  "description": "Default template for the loyalty widget in English",
  "loggedInTitle": "Your Loyalty Rewards",
  "loggedInSubTitle": "Keep shopping to earn streaks and unlock exclusive discounts.",
  "loggedOutTitle": "Earn Rewards Every Time You Shop",
  "loggedOutSubTitle": "Sign up to track your progress and unlock exclusive member discounts.",
  "joinNowButtonText": "Create Account",
  "signupUrl": "https://shop.example.com/register",
  "alreadyHaveAccountText": "Already a member?",
  "loginButtonText": "Sign In",
  "loginUrl": "https://shop.example.com/login",
  "streakSectionTitle": "Streaks",
  "noStreaksTextMessage": "No active streaks right now. Check back soon!",
  "challengeSectionTitle": "Challenges",
  "noChallengesTextMessage": "No active challenges right now. Check back soon!",
  "rewardsPageTitle": "My Rewards",
  "rewardsViewAllButtonText": "See All",
  "noRewardsTextMessage": "No rewards yet — start a streak or challenge to earn your first reward!",
  "rewardRedeemedLabel": "Used",
  "rewardExpiredLabel": "Expired",
  "copiedText": "Code copied!",
  "genericErrorMessage": "Oops! Something went wrong. Please try again."
}
```

---

To serve Spanish copy, update the template's language variant with `?languageCode=es`:

```json
{
  "loggedInTitle": "Tus Recompensas de Fidelidad",
  "loggedInSubTitle": "Sigue visitando para ganar puntos y desbloquear ofertas exclusivas.",
  "loggedOutTitle": "Gana Recompensas en Cada Visita",
  "loggedOutSubTitle": "Inicia sesión para seguir tu progreso.",
  "joinNowButtonText": "Crear cuenta",
  "loginButtonText": "Iniciar sesión",
  "streakSectionTitle": "Rachas",
  "challengeSectionTitle": "Desafíos",
  "rewardsPageTitle": "Mis Recompensas",
  "copiedText": "¡Copiado!"
}
```

Unset language fields fall back to the default language automatically.

---

## Fetching the template

**As a guest (no authentication required):**

```http
GET /api/v1.0/schema/template/record/{id}
```

**With localisation:**

```http
GET /api/v1.0/schema/template/record/{id}?languageCode=es
```

**As a logged in end user:**

```http
GET /api/v1.0/schema/template/record/{id}
x-enduser-access-token: <token>
x-account-id: <account-id>
```

---

## Access & permissions

| Caller | Allowed operations | Notes |
|---|---|---|
| Admin | CREATE · GET · LIST · UPDATE · DELETE | Full control over templates |
| End user | GET | Read-only access to the template |
| Guest user | GET | Template is publicly readable — widget works before login |

---

## Related resources

| Resource | Description |
|---|---|
| [Streak](/streak) | Streaks rendered in the `streakSectionTitle` section of the widget |
| [Challenge](/challenge) | Challenges rendered in the `challengeSectionTitle` section |
| [Reward Log](/reward_log) | Rewards displayed in the `rewardsPageTitle` section |
| [Floating Widget](/floating_widget) | The embeddable widget that uses this template for its copy |

---

## API reference

See the [API Reference](/api/template) for full request/response schemas and interactive examples for:

- `GET /schema/template/record` — get the template (supports `?languageCode=`)
- `POST /schema/template/record` — create a template
- `PATCH /schema/template/record/{id}` — update a template
- `DELETE /schema/template/record/{id}` — delete a template
