---
title: Subscribe to a Channel
description: Control which Live Update channel your Capacitor or Cordova app receives updates from — the default channel, versioned channels, and runtime selection.
---

# Subscribe to a Channel

Every device receives Live Updates from a single [channel](channels.md). This page covers how your app chooses which channel to subscribe to.

## The default channel

Every app starts with a channel named `default`. When your app doesn't request a specific channel, it receives updates from this one. The default channel exists mainly as a **fallback** to make getting started easy — you can publish your first update and watch it land without configuring any channels.

For production, we recommend moving to **versioned channels** — one channel per native app version — so a bundle only ever reaches devices that can run it. See [Binary-Compatible Changes](binary-compatible-changes.md) for why this matters, and the next section for how to set it up.

## Set the channel natively (recommended)

The cleanest approach is to configure the channel **natively at build time**. Your app code then doesn't need to manage channels at all, and you can derive the channel from the native version code to get versioned channels for free. See [Get Started](setup.md#make-updates-version-compatible) for the Android and iOS configuration.

## Select the channel at runtime

If you need to choose the channel dynamically — for example, to opt a user into a `beta` channel — pass the `channel` to the method that fetches updates. Passing it explicitly at the call site keeps the selected channel unambiguous.

### With `sync()`

=== "Capacitor"

    ```typescript
    import { LiveUpdate } from "@capawesome/capacitor-live-update";

    await LiveUpdate.sync({ channel: "beta" });
    ```

=== "Cordova"

    ```javascript
    await cordova.plugins.LiveUpdate.sync({ channel: "beta" });
    ```

### With `fetchLatestBundle()`

If you handle the [update lifecycle manually](manual-updates.md), pass the channel to `fetchLatestBundle()` instead:

=== "Capacitor"

    ```typescript
    import { LiveUpdate } from "@capawesome/capacitor-live-update";

    const result = await LiveUpdate.fetchLatestBundle({ channel: "beta" });
    ```

=== "Cordova"

    ```javascript
    const result = await cordova.plugins.LiveUpdate.fetchLatestBundle({ channel: "beta" });
    ```

### With `setChannel()`

You can also set the channel once with `setChannel()`, which persists it for all subsequent calls:

=== "Capacitor"

    ```typescript
    import { LiveUpdate } from "@capawesome/capacitor-live-update";

    await LiveUpdate.setChannel({ channel: "beta" });
    ```

=== "Cordova"

    ```javascript
    await cordova.plugins.LiveUpdate.setChannel({ channel: "beta" });
    ```

!!! warning "Prefer passing the channel directly"

    We don't recommend `setChannel()`. Passing the `channel` to `sync()` or `fetchLatestBundle()` on every call keeps the selected channel explicit at the call site and avoids relying on hidden, persisted state.

### Derive the channel from the version code

A common pattern is to compute the channel from the native version code, so updates stay [version-compatible](binary-compatible-changes.md):

=== "Capacitor"

    ```typescript
    import { LiveUpdate } from "@capawesome/capacitor-live-update";

    const { versionCode } = await LiveUpdate.getVersionCode();
    await LiveUpdate.sync({ channel: `production-${versionCode}` });
    ```

=== "Cordova"

    ```javascript
    const { versionCode } = await cordova.plugins.LiveUpdate.getVersionCode();
    await cordova.plugins.LiveUpdate.sync({ channel: `production-${versionCode}` });
    ```

## Next steps

- [Manage Channels](channels.md) — create and configure channels for staging and production.
- [Choose an Update Strategy](update-strategies.md) — control when updates are downloaded and applied.
