> For the complete documentation index, see [llms.txt](https://docs.limio.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.limio.com/developers/limio-sdk/advanced-methods/core-utilities-and-helpers.md).

# Core Utilities and Helpers

These utilities are imported from `@limio/sdk` (or its subpaths) and are available in any custom component. They are ordered below roughly by how commonly they are used across production components.

{% hint style="info" %}
Offer-specific helpers (`useOfferInfo`, `checkActiveOffers`, `groupOffers`) are documented on the [Page, Offers & Add-Ons](/developers/limio-sdk/page.md) page. Invoice fetching (`LimioFetchers.invoiceFetch`) is documented on the [Billing & Account](/developers/limio-sdk/billing-account.md) page.
{% endhint %}

***

## sanitiseHTML

An HTML sanitisation function that should be used whenever rendering content from offers or CMS fields via `dangerouslySetInnerHTML`. It uses [DOMPurify](https://github.com/cure53/DOMPurify) under the hood and automatically adds security attributes to links.

Most offer attributes that contain rich text — such as `offer_features__limio`, `display_description__limio`, or any `__limio_richtext` prop — should be passed through `sanitiseHTML` before rendering.

```typescript
function sanitiseHTML(dirty?: string): string
```

```tsx
import { sanitiseHTML } from "@limio/sdk"

const OfferFeatures = ({ offer }) => {
  const featuresHtml = offer.data.attributes.offer_features__limio

  return (
    <div dangerouslySetInnerHTML={{ __html: sanitiseHTML(featuresHtml) }} />
  )
}
```

**Behaviour:**

1. Strips all non-HTML-safe tags and attributes.
2. Preserves the `target` attribute on links.
3. Automatically adds `rel="noopener noreferrer"` to links with `target="_blank"`, and `rel="noopener"` to links with other target values.
4. Throws an error if called in a non-browser environment without DOM support (a Node.js version is available internally for SSR).

> **Important:** Always use `sanitiseHTML` when rendering user-controlled or offer-sourced HTML with `dangerouslySetInnerHTML`. This prevents XSS attacks from malicious content in offer attributes.

***

## ErrorBoundary

A React error boundary component that catches JavaScript errors in its child component tree and displays a fallback UI. Errors are automatically reported to Sentry.

Limio wraps individual components in an error boundary as part of the build step, so it is **not necessary to use at the top level**. However, `ErrorBoundary` is useful for wrapping specific children that may error where the parent component should remain functional — for example, a subscription details panel that fetches external data.

**Props:**

| Prop       | Type                                    | Description                        |
| ---------- | --------------------------------------- | ---------------------------------- |
| `children` | `React.ReactNode`                       | The component tree to wrap         |
| `ErrorUI`  | `React.ComponentType<{ error: Error }>` | Optional custom fallback component |

```tsx
import { ErrorBoundary } from "@limio/sdk"

const ParentComponent = ({ offer }) => {
  return (
    <div>
      <h1>This will always render</h1>
      <ErrorBoundary>
        <ChildThatMayError offer={offer} />
      </ErrorBoundary>
    </div>
  )
}
```

With a custom error UI:

```tsx
import { ErrorBoundary } from "@limio/sdk"

const MyErrorFallback = ({ error }) => (
  <p>Something went wrong: {error.message}</p>
)

const Component = () => (
  <ErrorBoundary ErrorUI={MyErrorFallback}>
    <RiskyComponent />
  </ErrorBoundary>
)
```

**Behaviour:**

1. Catches errors during rendering, in lifecycle methods, and in constructors of child components.
2. Does **not** catch errors in event handlers — use try/catch for those.
3. Logs all caught errors to Sentry with component stack info.
4. A HOC version is also available: `withErrorBoundary(Component, ErrorUI)`.

***

## Formatters

### formatCurrency

Formats a numeric amount with a currency code and optional locale. This is the most commonly used price formatter — use it in subscription tables, invoice lists, and anywhere you display monetary values.

```typescript
import { formatCurrency } from "@limio/sdk"

formatCurrency(amount: string | number, currencyCode: string, locality?: string): string
```

```javascript
formatCurrency(29.00, "USD")       // "$29.00"
formatCurrency(29.00, "GBP", "en") // "£29.00"
```

**Parameters:**

* `amount`: `string | number` — The amount to format.
* `currencyCode`: `string` — ISO 4217 currency code (e.g. `"USD"`, `"EUR"`).
* `locality` (optional): `string` — Locale for formatting.

### formatCurrencyForCurrentLocale

A convenience wrapper around `formatCurrency` that automatically resolves the locale from the `limio-country` cookie. Use this when you want locale-aware formatting without manually specifying a locale — common in cart summaries and checkout components.

```typescript
import { formatCurrencyForCurrentLocale } from "@limio/sdk"

formatCurrencyForCurrentLocale(amount: number | string, currency: string): string
```

```javascript
// UK user: formatCurrencyForCurrentLocale(10.99, "GBP") → "£10.99"
// US user: formatCurrencyForCurrentLocale(10.99, "USD") → "$10.99"
```

**Parameters:**

* `amount`: `number | string` — The amount to format.
* `currency`: `string` — The ISO 4217 currency code.

**Returns:** A formatted currency string using the browser's `Intl.NumberFormat` API.

> Use `formatCurrency` if you need to specify a locale explicitly.

### formatDate

Formats an ISO date string into a human-readable date. Use this when displaying subscription start/end dates, invoice dates, or billing cycle information.

```typescript
import { formatDate } from "@limio/sdk/date"

formatDate(date: string, format?: string): string
```

```javascript
formatDate("2023-12-14T11:19:29.442Z", "DATE_EN")   // "14 Dec 2023"
formatDate("2023-12-14T11:19:29.442Z", "DATE_FULL")  // "December 14, 2023"
formatDate("2023-12-14T11:19:29.442Z", "DATE_SHORT") // "14/12/2023"
formatDate("2023-12-14T11:19:29.442Z", "DATE_MED")   // "Dec 14, 2023"
```

**Parameters:**

* `date`: `string` — An ISO 8601 date string.
* `format` (optional): `string` — One of `"DATE_EN"`, `"DATE_FULL"`, `"DATE_SHORT"`, `"DATE_MED"`. If omitted, defaults to the Limio app locale settings.

### formatDisplayPrice

Formats a template string by replacing placeholders with values from a price object. Useful for rendering configurable price display strings that include currency symbols and amounts.

```typescript
import { formatDisplayPrice } from "@limio/sdk/price"

formatDisplayPrice(template: string, offerPrice: LimioPrice[]): string
```

```javascript
const priceString = "The price is {{currencySymbol}}{{amount}}."
const offerPrice = [{ currencyCode: "USD", value: "10.99" }]

formatDisplayPrice(priceString, offerPrice) // "The price is $10.99."
```

**Parameters:**

* `template`: `string` — A string containing placeholders (e.g. `{{currencyCode}}`, `{{amount}}`).
* `offerPrice`: `Array<LimioPrice>` — Array of price objects; the first element is used.

***

## Component Props

`useComponentProps` and `getPropsFromPackageJson` are the standard way to load the configurable props defined in your component's `package.json`. Almost every custom component uses this pattern to read the values that content editors set in the Page Builder.

```tsx
import packageData from "./package.json"
import { useComponentProps, getPropsFromPackageJson } from "@limio/sdk"

export function useComponentStaticProps() {
  const defaultComponentProps = getPropsFromPackageJson(packageData)
  const componentProps = useComponentProps(defaultComponentProps)
  return componentProps
}

function Component() {
  const { title, showFeatures, ctaColor } = useComponentStaticProps()
  // Use title, showFeatures, ctaColor in your component
}
```

For full details on defining `limioProps` in your package.json, see [Prop Types](/developers/custom-components/prop-types.md) and [Development Guidelines](/developers/custom-components/development-guidelines.md).

***

## Address Helpers

Utilities for working with addresses — formatting, metadata lookups, and country-specific form configuration. Import from `@limio/sdk/address`. These are primarily used in account management and checkout components that collect or display delivery and billing addresses.

### addressSummary

Takes a Limio address object and returns a formatted single-line string. Returns `"N/A"` if the address is empty. Use this in subscription detail tables and payment method displays.

```typescript
import { addressSummary } from "@limio/sdk/address"

addressSummary(customerDetails.deliveryAddress)
// "123 John Street, London, EC1 25X"
```

### formatCountry

Converts an alpha-2 country code into the full country name.

```typescript
import { formatCountry } from "@limio/sdk/address"

formatCountry("GB") // "United Kingdom"
formatCountry("US") // "United States"
```

### getAddressMetadata

Returns which address fields are required and which should be rendered for a given country. Use this to build dynamic address forms that adjust their inputs based on the selected country — for example, showing a "State" field for US/CA but not for UK addresses.

```typescript
import { getAddressMetadata } from "@limio/sdk/address"

const { requiredAddressFields, addressFieldsToRender } = getAddressMetadata("CA")

// requiredAddressFields: ["address1", "state", "postalCode", "country"]
// addressFieldsToRender: ["address1", "address2", "city", "state", "postalCode", "country"]
```

**Returns:**

* `requiredAddressFields`: `string[]` — Fields that must be filled in.
* `addressFieldsToRender`: `string[]` — Fields that should appear in the form.

### getCountryMetadata

Returns metadata for a country including its full name and ISO codes.

```typescript
import { getCountryMetadata } from "@limio/sdk/address"

getCountryMetadata("GB")
// { name: "United Kingdom", "alpha-2": "GB", "alpha-3": "GBR", "country-code": "826" }
```

***

## DateTime

Limio re-exports `DateTime` from [Luxon](https://moment.github.io/luxon/) for date handling. Use it when `formatDate` isn't flexible enough — for example, when calculating days until renewal or comparing subscription periods.

```typescript
import { DateTime } from "@limio/sdk"

const now = DateTime.local()
const nextBilling = DateTime.fromISO(subscription.data.end)
const daysUntilRenewal = nextBilling.diff(now, "days").days
```

***

## LimioAppSettings

Provides access to global application settings configured in Limio. Currently exposes the configured date format.

```typescript
import { LimioAppSettings } from "@limio/sdk"

const dateFormat = LimioAppSettings.getDateFormat()
```

**Available methods:**

| Method            | Returns  | Description                                                  |
| ----------------- | -------- | ------------------------------------------------------------ |
| `getDateFormat()` | `string` | The date format configured for the current Limio environment |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.limio.com/developers/limio-sdk/advanced-methods/core-utilities-and-helpers.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
