---
title: "Include a QR code to access your augmented reality (AR) maps on a mobile device | Augmented reality | JavaScript maps SDK"
description: "Provide a QR code to access mobile AR maps."
---

> 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.

# Include a QR code to access your augmented reality (AR) maps on a mobile device

To enhance the user experience, it is possible to incorporate a QR code picture alongside the three-dimensional model. This will enable users to effortlessly access the augmented reality model on their mobile device or AR viewer.

The [Augmented reality (AR) control](https://docs.maptiler.com/sdk-js/modules/ar/) adds a button on your map that enables the creation of a 3D representation of the current view, complete with 3D terrain and any additional layers you have applied. This functionality is compatible with **WebXR** or **Apple Quick Look**.

In this example, we employed the `qrcode-generator` library to produce the QR code. However, you have the flexibility to utilize your preferred approach for generating the QR code image.

### NPM module setup

```bash
npm install --save @maptiler/sdk @maptiler/ar-control
```

#### main.js

```js
import { Map, MapStyle, config } from '@maptiler/sdk';
import '@maptiler/sdk/dist/maptiler-sdk.css';
import { MaptilerARControl } from '@maptiler/ar-control';

config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';

const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

function generateQRCode() {
  // https://github.com/kazuhikoarase/qrcode-generator/tree/master/js
  const qr = qrcode(0, "M");
  qr.addData(location.href);
  qr.make();
  return qr.createDataURL(10, 10);
}

// Creating a map
const map = new Map({
  container: 'map',
  style: MapStyle.OUTDOOR,
  zoom: 12,
  center: [-116.22335, 51.4117],
  hash: true,
});

// Waiting for the map to be ready
map.on("load", (e) => {
  const qrCodeOptions = isMobile ? {activateAR: true} : {
    logo: generateQRCode(),
    logoClass: "qr-code",
    activateAR: true
  }

  const arControl = new MaptilerARControl(qrCodeOptions);

  arControl.on("computeStart", (e) => {
    overlay.style.display = "inherit";

    if (!isMobile) {
      arControl.updateLogo(generateQRCode())
    }
  })

  arControl.on("computeEnd", (e) => {
    overlay.style.display = "none";
  })

  map.addControl(arControl, "top-left");
})
```

#### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="robots" content="noindex">
  <title>Include a QR code to access your augmented reality (AR) maps on a mobile device | NPM example</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>
  <div id="overlay">
    <div class="blink_me">computing model</div>
  </div>

  <div id="map"></div>
  <script type="module" src="./main.js"></script>
</body>
</html>
```

#### style.css

```css
html, body {
  margin: 0;
}

#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

#overlay {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100vw;
  height: 100vh;
  background-color: #ffffff;
  z-index: 3;
  display: none;
}

#overlay div {
  color: rgb(71, 76, 87);
  position: absolute;
  width: fit-content;
  height: fit-content;
  right: 0;
  left: 0;
  bottom: 0;
  top: 0;
  margin: auto;
  padding: 30px;
  font: 12px/20px Helvetica Neue,Arial,Helvetica,sans-serif;
}

.blink_me {
  animation: blinker 1s linear infinite;
}

@keyframes blinker {
  50% {
    opacity: 0.2;
  }
}

.qr-code {
  position: absolute;
  bottom: 0;
  left: 0;
  margin: 20px;
  height: 120px;
  border: 2px white solid;
  border-radius: 5px;
}
```

### Basic JavaScript setup

```html
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>MapTiler AR Control</title>
    <script src="https://cdn.maptiler.com/maptiler-sdk-js/v4.2.0/maptiler-sdk.umd.min.js"></script>
    <link href="https://cdn.maptiler.com/maptiler-sdk-js/v4.2.0/maptiler-sdk.css" rel="stylesheet" />
    <script src="https://cdn.maptiler.com/maptiler-ar-control/v3.0.3/maptiler-ar-control.umd.min.js"></script>

    <!-- Importing QR code library -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcode-generator/1.4.4/qrcode.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

    <style>
      html, body {
        margin: 0;
      }

      #map {
        position: absolute;
        top: 0;
        bottom: 0;
        width: 100%;
      }

      #overlay {
        position: absolute;
        top: 0;
        bottom: 0;
        width: 100vw;
        height: 100vh;
        background-color: #ffffff;
        z-index: 3;
        display: none;
      }

      #overlay div {
        color: rgb(71, 76, 87);
        position: absolute;
        width: fit-content;
        height: fit-content;
        right: 0;
        left: 0;
        bottom: 0;
        top: 0;
        margin: auto;
        padding: 30px;
        font: 12px/20px Helvetica Neue,Arial,Helvetica,sans-serif;
      }

      .blink_me {
        animation: blinker 1s linear infinite;
      }

      @keyframes blinker {
        50% {
          opacity: 0.2;
        }
      }

      .qr-code {
        position: absolute;
        bottom: 0;
        left: 0;
        margin: 20px;
        height: 120px;
        border: 2px white solid;
        border-radius: 5px;
      }
    </style>
  </head>
  <body>
    <div id="overlay">
      <div class="blink_me">computing model</div>
    </div>

    <div id="map"></div>
    <script>
      maptilersdk.config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';

      const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

      function generateQRCode() {
        // https://github.com/kazuhikoarase/qrcode-generator/tree/master/js
        const qr = qrcode(0, "M");
        qr.addData(location.href);
        qr.make();
        return qr.createDataURL(10, 10);
      }
      
      // Creating a map
      const map = new maptilersdk.Map({
        container: 'map',
        style: maptilersdk.MapStyle.OUTDOOR,
        zoom: 12,
        center: [-116.22335, 51.4117],
        hash: true,
      });

      // Waiting for the map to be ready
      map.on("load", (e) => {
        const qrCodeOptions = isMobile ? {activateAR: true} : {
          logo: generateQRCode(),
          logoClass: "qr-code",
          activateAR: true
        }

        const arControl = new maptilerarcontrol.MaptilerARControl(qrCodeOptions);

        arControl.on("computeStart", (e) => {
          overlay.style.display = "inherit";

          if (!isMobile) {
            arControl.updateLogo(generateQRCode())
          }
        })

        arControl.on("computeEnd", (e) => {
          overlay.style.display = "none";
        })

        map.addControl(arControl, "top-left");
      })

    </script>
  </body>
</html>
```

## Related examples

### [Custom AR experience](https://docs.maptiler.com/sdk-js/examples/ar-control-custom/)

Examples

Customize the appearance of the augmented reality map control.

### [Add GeoJSON to AR maps](https://docs.maptiler.com/sdk-js/examples/ar-control-geojson-line/)

Examples

Display GeoJSON biking or hiking routes in AR maps.

### [Trigger AR control actions](https://docs.maptiler.com/sdk-js/examples/ar-control-no-button/)

Examples

Trigger AR map control actions using keyboard input.

### [Start with AR maps](https://docs.maptiler.com/sdk-js/examples/ar-control/)

Examples

Add an AR control button to map 3D viewports.
