---
title: "How to use Cesium JS: step-by-step tutorial | Cesium"
description: "Step-by-step tutorial for creating 3D maps using Cesium JS."
---

> For AI agents: a documentation index is available at [/llms.txt](https://docs.maptiler.com/llms.txt). Markdown versions of all pages are available by appending .md to any URL.

# How to use Cesium JS: step-by-step tutorial

In this step-by-step tutorial, you’ll learn how to create a [3D map](https://www.maptiler.com/maps/3d/) and display it on a web page. Together we will make a simple full-screen map application, serving as a practical example of how to seamlessly integrate MapTiler maps with Cesium into your web mapping application.

By the end of this tutorial, you will be able to develop a full-screen 3D globe map. Your final map will resemble the following example:

1.  Create a basic HTML file.
    
    ```html
    <!DOCTYPE html>
       <html lang="en">
       <head>
         <meta charset="UTF-8">
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
         <title>Display a map in Cesium JS</title>
         <style>
           body {
             margin: 0;
             padding: 0;
           }
         </style>
       </head>
       <body>
    
       </body>
       <script>
    
       </script>
       </html>
    ```
    
2.  Include the Cesium JavaScript and CSS files in the `<head>` of your HTML file.
    
    ```html
    <title>Display a map in Cesium JS</title>
      <script src="https://cesium.com/downloads/cesiumjs/releases/1.116/Build/Cesium/Cesium.js"></script>
      <link href="https://cesium.com/downloads/cesiumjs/releases/1.116/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
      <style>
        body {
          margin: 0;
          padding: 0;
        }
      </style>
    ```
    
3.  Create a `<div>` element with a certain id where you want your map to be.
    
    Add `<div>` tag to your page. This div will be the container where the map will be loaded.
    
    ```html
    <body>
         <div id="cesiumContainer">
       
         </div>
       </body>
    ```
    
4.  The div must have a non-zero height.
    

```css
body {
  margin: 0;
  padding: 0;
}
#cesiumContainer {position: absolute; top: 0; right: 0; bottom: 0; left: 0;}
```

1.  Add the MapTiler logo to the map. Check the [MapTiler map data licenses](https://www.maptiler.com/copyright/)

```html
<body>
    <div id="cesiumContainer">
      <a href="https://www.maptiler.com" style="position:absolute;right:10px;bottom:10px;z-index:999;"><img src="https://api.maptiler.com/resources/logo.svg" alt="MapTiler logo"></a>
    </div>
  </body>
```

1.  Initialize the Cesium Viewer in the HTML element with the id `cesiumContainer` and add attribution.
    
    ```html
    <script>
      const viewer = new Cesium.Viewer('cesiumContainer', {
        animation: false,
        baseLayerPicker: false,
        navigationHelpButton: false,
        sceneModePicker: false,
        homeButton: false,
        geocoder: false,
        fullscreenButton: false,
        timeline: false,
      });
      const credit = new Cesium.Credit(`<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>`, true)
      viewer.creditDisplay.addStaticCredit(credit);
    </script>
    ```
    
2.  Set the initial camera view to the given longitude, latitude, and height.
    

```js
const viewer = new Cesium.Viewer('cesiumContainer', {
    animation: false,
    baseLayerPicker: false,
    navigationHelpButton: false,
    sceneModePicker: false,
    homeButton: false,
    geocoder: false,
    fullscreenButton: false,
    timeline: false,
  });
  viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(8.67, 46.72, 4500),
    orientation: {
      pitch: Cesium.Math.toRadians(-20)
    }
  });
```

1.  Add the MapTier API Key. Replace `YOUR_MAPTILER_API_KEY_HERE` with [your own API key](https://cloud.maptiler.com/account/keys/). Make sure to [secure the key](https://docs.maptiler.com/guides/credentials/api-key/#secure-key) before you publish it.

```js
const key = 'YOUR_MAPTILER_API_KEY_HERE';
  const viewer = new Cesium.Viewer('cesiumContainer', {
    animation: false,
    baseLayerPicker: false,
    navigationHelpButton: false,
    sceneModePicker: false,
    homeButton: false,
    geocoder: false,
    fullscreenButton: false,
    timeline: false,
  });
```

1.  Add the [terrain](https://cesium.com/learn/cesiumjs/ref-doc/Terrain.html) to see the terrain in 3D. We will use the [Terrain 3D - Cesium quantized mesh](https://cloud.maptiler.com/tiles/terrain-quantized-mesh-v2/) as geometry for the terrain surface.

```js
const viewer = new Cesium.Viewer('cesiumContainer', {
    animation: false,
    baseLayerPicker: false,
    navigationHelpButton: false,
    sceneModePicker: false,
    homeButton: false,
    geocoder: false,
    fullscreenButton: false,
    timeline: false,
    terrain: new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl(`https://api.maptiler.com/tiles/terrain-quantized-mesh-v2/?key=${key}`, {
      requestVertexNormals: true
    }))
  });
```

1.  Add the [ImageryLayer](https://cesium.com/learn/cesiumjs/ref-doc/ImageryLayer.html) to provide the images to display on the terrain surface. We will use the [MapTiler Satellite services](https://www.maptiler.com/satellite/). You can use any other map you have on [MapTiler maps](https://cloud.maptiler.com/maps/) as an imageProvider.

```js
const viewer = new Cesium.Viewer('cesiumContainer', {
    animation: false,
    baseLayerPicker: false,
    navigationHelpButton: false,
    sceneModePicker: false,
    homeButton: false,
    geocoder: false,
    fullscreenButton: false,
    timeline: false,
    terrain: new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl(`https://api.maptiler.com/tiles/terrain-quantized-mesh-v2/?key=${key}`, {
      requestVertexNormals: true
    }))
    baseLayer: new Cesium.ImageryLayer( new Cesium.UrlTemplateImageryProvider({
      url: `https://api.maptiler.com/maps/satellite-v4/{z}/{x}/{y}.jpg?key=${key}`,
      minimumLevel: 0,
      maximumLevel: 20,
      tileWidth: 512,
      tileHeight: 512,
    })),
  });
```

### Complete source code

```html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Display a map in Cesium JS</title>
  <script src="https://cesium.com/downloads/cesiumjs/releases/1.116/Build/Cesium/Cesium.js"></script>
  <link href="https://cesium.com/downloads/cesiumjs/releases/1.116/Build/Cesium/Widgets/widgets.css"
    rel="stylesheet">
  <style>
    body {
      margin: 0;
      padding: 0;
    }

    #cesiumContainer {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }
  </style>
</head>

<body>
  <div id="cesiumContainer">
    <a href="https://www.maptiler.com" style="position:absolute;right:5px;bottom:5px;z-index:999;"><img
        src="https://api.maptiler.com/resources/logo.svg" alt="MapTiler logo"></a>
  </div>
</body>
<script>
  const key = 'YOUR_MAPTILER_API_KEY_HERE';
  const viewer = new Cesium.Viewer('cesiumContainer', {
    animation: false,
    baseLayerPicker: false,
    navigationHelpButton: false,
    sceneModePicker: false,
    homeButton: false,
    geocoder: false,
    fullscreenButton: false,
    timeline: false,
    terrain: new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl(`https://api.maptiler.com/tiles/terrain-quantized-mesh-v2/?key=${key}`, {
      requestVertexNormals: true
    })),
    baseLayer: new Cesium.ImageryLayer(new Cesium.UrlTemplateImageryProvider({
      url: `https://api.maptiler.com/maps/satellite-v4/{z}/{x}/{y}.jpg?key=${key}`,
      minimumLevel: 0,
      maximumLevel: 20,
      tileWidth: 512,
      tileHeight: 512,
    })),
  });
  const credit = new Cesium.Credit(`<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>`, true)
  viewer.creditDisplay.addStaticCredit(credit);
  viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(8.67, 46.72, 4500),
    orientation: {
      pitch: Cesium.Math.toRadians(-20)
    }
  });
</script>

</html>
```

1.  Install the npm package.
    
    ```bash
    npm install --save cesium
    ```
    
2.  Create the cesiumContainer style. Add the cesiumContainer style to your stylesheet. The div must have non-zero height.
    

```css
body {
  margin: 0;
  padding: 0;
}
#cesiumContainer {position: absolute; top: 0; right: 0; bottom: 0; left: 0;}
```

1.  Create a `<div>` element with a certain id where you want your map to be.
    
    Add `<div>` tag into your page. This div will be the container where the map will be loaded.
    
    ```html
    <div id="cesiumContainer"></div>
    ```
    
2.  Include the CSS file.
    
    If you have a bundler that can handle CSS, you can import the CSS from ol/ol.css.
    
    ```js
    import 'cesium/Build/Cesium/Widgets/widgets.css';
    ```
    
    Note
    
    Including the CSS file using a `<link>` in the head of the document via the CDN is the easiest way.
    
    ```html
    <link href="https://cesium.com/downloads/cesiumjs/releases/1.116/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
    ```
    
3.  Add the MapTiler logo to the map. Check the [MapTiler map data licenses](https://www.maptiler.com/copyright/)
    

```html
<div id="cesiumContainer">
  <a href="https://www.maptiler.com" style="position:absolute;right:10px;bottom:10px;z-index:999;"><img src="https://api.maptiler.com/resources/logo.svg" alt="MapTiler logo"></a>
</div>
```

1.  Initialize the Cesium Viewer in the HTML element with the id `cesiumContainer` and add attribution.

```js
import { Viewer } from 'cesium';
import 'cesium/Build/Cesium/Widgets/widgets.css';

const viewer = new Viewer('cesiumContainer', {
  animation: false,
  baseLayerPicker: false,
  navigationHelpButton: false,
  sceneModePicker: false,
  homeButton: false,
  geocoder: false,
  fullscreenButton: false,
  timeline: false,
});
const credit = new Cesium.Credit(`<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>`, true)
viewer.creditDisplay.addStaticCredit(credit);
```

1.  Update imports

```js
import { Viewer, Cartesian3, Math as CesiumMath } from 'cesium';
```

1.  Set the initial camera view to the given longitude, latitude, and height.

```js
viewer.camera.setView({
  destination: Cartesian3.fromDegrees(8.67, 46.72, 4500),
  orientation: {
    pitch: CesiumMath.toRadians(-20)
  }
});
```

1.  Add the MapTier API Key. Replace `YOUR_MAPTILER_API_KEY_HERE` with [your own API key](https://cloud.maptiler.com/account/keys/). Make sure to [secure the key](https://docs.maptiler.com/guides/credentials/api-key/#secure-key) before you publish it.

```js
const key = 'YOUR_MAPTILER_API_KEY_HERE';
  const viewer = new Viewer('cesiumContainer', {
    animation: false,
    baseLayerPicker: false,
    navigationHelpButton: false,
    sceneModePicker: false,
    homeButton: false,
    geocoder: false,
    fullscreenButton: false,
    timeline: false,
  });
```

1.  Update imports

```js
import { Viewer, Cartesian3, Math as CesiumMath, Terrain, CesiumTerrainProvider, Credit } from 'cesium';
```

1.  Add the [terrain](https://cesium.com/learn/cesiumjs/ref-doc/Terrain.html) to see the terrain in 3D. We will use the [Terrain 3D - Cesium quantized mesh](https://cloud.maptiler.com/tiles/terrain-quantized-mesh-v2/) as geometry for the terrain surface.

```js
const viewer = new Viewer('cesiumContainer', {
    animation: false,
    baseLayerPicker: false,
    navigationHelpButton: false,
    sceneModePicker: false,
    homeButton: false,
    geocoder: false,
    fullscreenButton: false,
    timeline: false,
    terrain: new Terrain(CesiumTerrainProvider.fromUrl(`https://api.maptiler.com/tiles/terrain-quantized-mesh-v2/?key=${key}`, {
      requestVertexNormals: true
    })),
  });
```

1.  Update imports

```js
import { Viewer, Cartesian3, Math as CesiumMath, Terrain, CesiumTerrainProvider, Credit, ImageryLayer, UrlTemplateImageryProvider } from 'cesium';
```

1.  Add the [ImageryLayer](https://cesium.com/learn/cesiumjs/ref-doc/ImageryLayer.html) to provide the images to display on the terrain surface. We will use the [MapTiler Satellite services](https://www.maptiler.com/satellite/). You can use any other map you have on [MapTiler maps](https://cloud.maptiler.com/maps/) as an imageProvider.

```js
const viewer = new Viewer('cesiumContainer', {
    animation: false,
    baseLayerPicker: false,
    navigationHelpButton: false,
    sceneModePicker: false,
    homeButton: false,
    geocoder: false,
    fullscreenButton: false,
    timeline: false,
    terrain: new Terrain(CesiumTerrainProvider.fromUrl(`https://api.maptiler.com/tiles/terrain-quantized-mesh-v2/?key=${key}`, {
      requestVertexNormals: true
    })),
    baseLayer: new ImageryLayer( new UrlTemplateImageryProvider({
      url: `https://api.maptiler.com/maps/satellite-v4/{z}/{x}/{y}.jpg?key=${key}`,
      minimumLevel: 0,
      maximumLevel: 20,
      tileWidth: 512,
      tileHeight: 512,
    })),
  });
```

### Complete source code

```bash
npm install --save cesium
```

#### main.js

```js
import { Viewer, Terrain, Credit, ImageryLayer, UrlTemplateImageryProvider, Cartesian3, CesiumTerrainProvider, Math as CesiumMath } from 'cesium';
import 'cesium/Build/Cesium/Widgets/widgets.css';

const key = 'YOUR_MAPTILER_API_KEY_HERE';
const viewer = new Viewer('cesiumContainer', {
  animation: false,
  baseLayerPicker: false,
  navigationHelpButton: false,
  sceneModePicker: false,
  homeButton: false,
  geocoder: false,
  fullscreenButton: false,
  timeline: false,
  terrain: new Terrain(CesiumTerrainProvider.fromUrl(`https://api.maptiler.com/tiles/terrain-quantized-mesh-v2/?key=${key}`, {
    requestVertexNormals: true
  })),
  baseLayer: new ImageryLayer( new UrlTemplateImageryProvider({
    url: `https://api.maptiler.com/maps/satellite-v4/{z}/{x}/{y}.jpg?key=${key}`,
    minimumLevel: 0,
    maximumLevel: 20,
    tileWidth: 512,
    tileHeight: 512,
  })),
});
const credit = new Cesium.Credit(`<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>`, true)
viewer.creditDisplay.addStaticCredit(credit);
viewer.camera.setView({
  destination: Cartesian3.fromDegrees(8.67, 46.72, 4500),
  orientation: {
    pitch: CesiumMath.toRadians(-20)
  }
});
```

#### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="robots" content="noindex">
  <title>Display a map in Cesium JS</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>
  <div id="cesiumContainer">
    <a href="https://www.maptiler.com" style="position:absolute;right:10px;bottom:10px;z-index:999;"><img src="https://api.maptiler.com/resources/logo.svg" alt="MapTiler logo"></a>
  </div>
  <script type="module" src="./main.js"></script>
</body>
</html>
```

#### style.css

```css
body {
  margin: 0;
  padding: 0;
}
#cesiumContainer {position: absolute; top: 0; right: 0; bottom: 0; left: 0;}
```

## Learn more

To learn more about 3D terrain data modeling, read the [3D vector tiles with Cesium](https://docs.maptiler.com/guides/self-hosting/self-hosted-maps/3d-vector-tiles-with-cesium) article.
