# How to Configure a Cesium Ion Token for 3D Globe Rendering in GeoLibre

> Easily configure your Cesium Ion token in GeoLibre for stunning 3D globe rendering. Learn how to set the token and pass it to CesiumCanvas for world imagery and terrain.

- Repository: [Open Geospatial Solutions/GeoLibre](https://github.com/opengeos/GeoLibre)
- Tags: how-to-guide
- Published: 2026-08-01

---

**Set `VITE_CESIUM_TOKEN` or `CESIUM_TOKEN` in your environment, then pass the token to the `CesiumCanvas` component via its `ionToken` prop to enable Cesium Ion world imagery and terrain.**

GeoLibre renders interactive 3D globes using **CesiumJS** through the `CesiumCanvas` component in the `@geolibre/map` package. Configuring a Cesium Ion token unlocks high-resolution world terrain and satellite imagery, while a missing token triggers an automatic fallback to OpenStreetMap. This guide walks through every layer of the token configuration system as implemented in the `opengeos/GeoLibre` source code.

## Where the Token Originates

GeoLibre's token resolution follows a priority chain from build-time injection to runtime environment lookup.

### Runtime Environment Detection

The `@geolibre/core` package exposes `getCesiumIonToken()` in [`packages/core/src/runtime-env.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/core/src/runtime-env.ts). This function checks for two environment variable names:

```ts
export function getCesiumIonToken(env?: Record<string, string | undefined>): string | undefined {
  const runtimeEnv = env ?? process.env;
  const trimmed = runtimeEnv.VITE_CESIUM_TOKEN?.trim() || runtimeEnv.CESIUM_TOKEN?.trim();
  return trimmed?.length ? trimmed : undefined;
}

```

- **`VITE_CESIUM_TOKEN`** — Takes precedence; injected by Vite at build time for client-side access
- **`CESIUM_TOKEN`** — Fallback for server-side or non-Vite environments

The function trims whitespace and returns `undefined` for empty strings, preventing invalid token errors.

### Build-Time Injection

The desktop app configuration at [`apps/geolibre-desktop/vite.config.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/vite.config.ts) bridges the gap between bare `CESIUM_TOKEN` and Vite's required `VITE_` prefix:

```ts
// vite.config.ts (excerpt)
export default defineConfig({
  define: {
    'import.meta.env.VITE_CESIUM_TOKEN': JSON.stringify(process.env.CESIUM_TOKEN)
  }
})

```

This ensures existing `CESIUM_TOKEN` values are automatically available to the client bundle without manual renaming.

## How the Token Propagates to the Globe

### UI Layer: MapGrid

The `MapGrid` component in [`apps/geolibre-desktop/src/components/layout/MapGrid.tsx`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/components/layout/MapGrid.tsx) reads the token at render time using React state:

```tsx
const [cesiumToken, setCesiumToken] = useState<string | undefined>(() => getCesiumIonToken());

```

Storing the token in state allows runtime refresh without rebuilding the application—users can update their token through a settings dialog and call `setCesiumToken(getCesiumIonToken())` to apply changes immediately.

### Canvas Layer: CesiumCanvas

The `CesiumCanvas` component receives the token via its `ionToken` prop and applies it during CesiumJS initialization in [`packages/map/src/CesiumCanvas.tsx`](https://github.com/opengeos/GeoLibre/blob/main/packages/map/src/CesiumCanvas.tsx):

```tsx
const ionTokenRef = useRef<string | undefined>(ionToken);

// After dynamic import of CesiumJS
if (ionTokenRef.current) {
  Cesium.Ion.defaultAccessToken = ionTokenRef.current;
}

```

The token assignment happens once, before viewer construction, ensuring all Ion-dependent resources use authenticated requests.

## What the Token Enables

### With a Valid Token

When `ionToken` is present, `CesiumCanvas` configures:

- **Cesium World Terrain** — High-resolution global elevation via `Cesium.createWorldTerrainAsync()`
- **Cesium Ion Imagery** — Default Bing Maps satellite layers from Cesium's asset server

### Without a Token

The component automatically falls back to OpenStreetMap imagery by setting a custom `baseLayer` in the viewer constructor. The 3D globe remains functional but lacks premium terrain and imagery quality.

## Configuration Methods

### Method 1: Environment File (Recommended)

Create or edit `.env` in your project root:

```dotenv
VITE_CESIUM_TOKEN=your-ion-jwt-token

```

Vite injects this value at build time. `getCesiumIonToken()` picks it up automatically in both development and production.

### Method 2: Pass Token Directly to CesiumCanvas

For custom implementations or testing:

```tsx
import { CesiumCanvas } from "@geolibre/map";

<CesiumCanvas 
  viewId="main-globe" 
  ionToken={process.env.VITE_CESIUM_TOKEN} 
/>

```

### Method 3: Runtime Refresh from UI

Enable user-controlled token updates:

```tsx
import { getCesiumIonToken } from "@geolibre/core";

function TokenSettings() {
  const [cesiumToken, setCesiumToken] = useState<string | undefined>(
    () => getCesiumIonToken()
  );

  const refreshToken = () => setCesiumToken(getCesiumIonToken());

  return (
    <div>
      <input 
        type="text" 
        onChange={(e) => {
          // Persist to env or storage, then:
          refreshToken();
        }}
      />
      <CesiumCanvas viewId="globe" ionToken={cesiumToken} />
    </div>
  );
}

```

### Method 4: Programmatic Fallback Handling

Detect missing tokens for conditional UI messaging:

```ts
const token = getCesiumIonToken();

if (!token) {
  console.warn("Cesium Ion token not set – OSM fallback active");
  showNotification("Globe running in basic mode. Add Cesium token for terrain.");
}

```

## Architecture Reference

| File | Purpose |
|------|---------|
| [`packages/map/src/CesiumCanvas.tsx`](https://github.com/opengeos/GeoLibre/blob/main/packages/map/src/CesiumCanvas.tsx) | Creates Cesium viewer, applies `Cesium.Ion.defaultAccessToken`, manages terrain fallback |
| [`packages/core/src/runtime-env.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/core/src/runtime-env.ts) | Exports `getCesiumIonToken()` with `VITE_CESIUM_TOKEN` > `CESIUM_TOKEN` priority |
| [`apps/geolibre-desktop/vite.config.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/vite.config.ts) | Injects `CESIUM_TOKEN` into `VITE_CESIUM_TOKEN` for client access |
| [`apps/geolibre-desktop/src/components/layout/MapGrid.tsx`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/components/layout/MapGrid.tsx) | UI integration: reads token into React state for live updates |

## Summary

- **Primary method**: Set `VITE_CESIUM_TOKEN` in `.env` for automatic detection by `getCesiumIonToken()`
- **Build bridge**: [`vite.config.ts`](https://github.com/opengeos/GeoLibre/blob/main/vite.config.ts) maps `CESIUM_TOKEN` to `VITE_CESIUM_TOKEN` for compatibility
- **Runtime propagation**: `MapGrid` reads via `getCesiumIonToken()`, `CesiumCanvas` receives via `ionToken` prop
- **Application**: Assigned to `Cesium.Ion.defaultAccessToken` before viewer initialization
- **Fallback**: Missing token triggers OpenStreetMap imagery instead of Cesium Ion resources

## Frequently Asked Questions

### What happens if I don't configure a Cesium Ion token?

The globe renders with OpenStreetMap as the base imagery layer and flat terrain. The 3D visualization remains functional but lacks high-resolution satellite imagery and accurate elevation data provided by Cesium Ion services.

### Can I change the token without rebuilding the application?

Yes. Store the token in React state as implemented in [`MapGrid.tsx`](https://github.com/opengeos/GeoLibre/blob/main/MapGrid.tsx), then update that state when users modify their token through a settings UI. The `CesiumCanvas` component re-renders and applies the new token to `Cesium.Ion.defaultAccessToken`.

### Why does GeoLibre use `VITE_CESIUM_TOKEN` instead of just `CESIUM_TOKEN`?

Vite requires environment variables exposed to the client to use the `VITE_` prefix for security. The `getCesiumIonToken()` helper accepts both names, with `VITE_CESIUM_TOKEN` taking precedence. The build configuration automatically maps bare `CESIUM_TOKEN` to the prefixed variant.

### Where can I obtain a Cesium Ion token?

Create a free account at [cesium.com/ion](https://cesium.com/ion), then generate an access token from your dashboard. Free tiers include sufficient credits for development and moderate usage.