> ## Documentation Index
> Fetch the complete documentation index at: https://docs.napps.io/llms.txt
> Use this file to discover all available pages before exploring further.

# @napps/component-extension services

This page lists the service objects and global helpers exported by `@napps/component-extension`.
Use the [Services](/introduction-1) guides for behavior-oriented examples.

## `NAPPS`

`NAPPS` is the proxy object used when you prefer an explicit object over ambient globals.

```ts theme={null}
import { NAPPS } from "@napps/component-extension";

const count = NAPPS.cartService?.getCartItemsCount() ?? 0;
const result = await NAPPS.storefrontCall<{
  product: { id: string; title: string } | null;
}>(
  `query Product($id: ID!) {
    product(id: $id) { id title }
  }`,
  { id: "gid://shopify/Product/123" }
);
```

The proxy exposes these members:

```ts theme={null}
class NAPPSProxy {
  storefrontCall<T>(query: string, properties?: object): Promise<GraphQLResponse<T>>;
  customerCall<T>(query: string, properties?: object): Promise<GraphQLResponse<T>>;
  readonly sessionStorage: SessionStorage;
  readonly AppUtils: AppUtils;
  readonly product: Product | undefined;
  readonly productService: ProductService;
  readonly metaObjectService: MetaObjectService;
  readonly cartService: CartService | undefined;
  readonly CartOperations: CartOperations | undefined;
  readonly AppNavigation: AppNavigation;
  readonly customerContext: CustomerContextService;
  readonly SafeArea: SafeArea;
}
```

The same services are available as globals where the active surface registers them. Prefer the
proxy in reusable modules because it makes the dependency visible and keeps calls easy to mock.

## Storefront and customer calls

Both APIs return a typed GraphQL envelope. The optional `properties` object is passed as the
request properties/variables object supported by the host.

```ts theme={null}
interface GraphQLResponse<T> {
  data: T;
  extensions: object | undefined;
  errors: object[] | undefined;
}

function storefrontCall<T>(
  query: string,
  properties?: object
): Promise<GraphQLResponse<T>>;

function customerCall<T>(
  query: string,
  properties?: object
): Promise<GraphQLResponse<T>>;
```

Deprecated calls will be blocked. Migrate to the supported generic signature above: put the
operation document in `query`, pass request values in the second `properties` object, and read
`data` and `errors` from the returned envelope. Do not depend on older positional overloads.

## App utilities

```ts theme={null}
interface AppUtils {
  readonly country: string;
  readonly locale: string;
  formatCurrency(value: string, currency?: string): string;
}
```

`country` and `locale` describe the current app context. `formatCurrency` returns a localized
display string; it does not change the input amount.

## Cart service

```ts theme={null}
interface CartService {
  getCartItemsCount(): number;
  getLineItems(): CartLineItem[];
  addLineItem(
    productID: string,
    variantMetaID: string,
    qty: number,
    attributes?: Record<string, string>
  ): Promise<boolean>;
  updateLineItem(
    lineItemID: string,
    qty: number,
    attributes?: Record<string, string>,
    matchingLayoutID?: number
  ): void;
  removeLineItem(lineItemID: string): Promise<void>;
  applyOperations(ops: CartOperation[]): Promise<void>;
}
```

The service is optional on surfaces that do not have a cart host. Check it before using it.
Use [`CartOperations`](/typescript-reference/component-extensions#cart-operations) when you
need to return a batch of mutations from an extension.

## App navigation

```ts theme={null}
interface AppNavigation {
  navigateToCart(): void;
  navigateToProductDetail(productID: string): void;
  navigateToProductQuickAdd(productID: string): void;
  navigateToCollection(collectionID: string, title?: string): void;
  navigateToExternalPage(url: string, title: string): void;
  navigateToPreferredStorePicker(variantID?: string): void;
  navigateToStoreAvailability(): void;
}
```

Navigation methods hand control to the native app. Validate external URLs in your extension before
calling `navigateToExternalPage`.

## Product and metaobject services

```ts theme={null}
interface ProductService {
  getProductMetaFields(
    productID: string,
    metaFieldsKeys: string[]
  ): Promise<MetaFieldsByNamespace>;
  getProductByHandle(handle: string): Promise<Product | null>;
  getProductByID(productID: string): Promise<Product | null>;
  getProductVariantStoreAvailability(
    variantID: string
  ): Promise<StoreProductAvailability[]>;
}

interface MetaObjectService {
  getAllMetaObjectsByType(type: string): Promise<MetaObject[]>;
  getMetaObjectsByType(
    type: string,
    limit: number,
    after?: string
  ): Promise<MetaObjectsPage>;
  getMetaObjectByHandle(type: string, handle: string): Promise<MetaObject | null>;
}
```

Product lookup methods resolve to `null` when no matching object exists. Treat these promises as
the supported lookup APIs and handle `null`; do not infer that a missing product is exceptional.

## Customer context

```ts theme={null}
interface CustomerContextService {
  getCustomer(): CustomerInfo | null;
  isAuthenticated(): boolean;
}

interface CustomerInfo {
  readonly name: string;
  readonly email: string;
}
```

Authentication can change while the app is running. Read the context when the action occurs rather
than caching it indefinitely.

## Safe-area insets

```ts theme={null}
interface SafeArea {
  get(): SafeAreaInsets;
  subscribe(callback: (insets: SafeAreaInsets) => void): number;
  unsubscribe(id: number): void;
}

interface SafeAreaInsets {
  top: number;
  bottom: number;
  start: number;
  end: number;
}
```

Values are density-independent units. `subscribe` invokes the callback immediately with the
current snapshot and returns an ID for cleanup.

## Storage access

```ts theme={null}
interface SessionStorage {
  readonly length: number;
  clear(): void;
  getItem(key: string): string | null;
  key(index: number): string | null;
  removeItem(key: string): void;
  setItem(key: string, value: string): void;
}
```

`sessionStorage` is synchronous and in-memory. For persistent scoped storage, see [Runtime APIs](/runtime-apis)
and the `AppStorage` declarations in [`@napps/nodes` runtime](/typescript-reference/nodes-runtime).
