# Build a public application

Here you will learn the basic concepts required to create a public web application using CARTO, compatible with any Javascript Development Framework. With CARTO you don't need to be a geospatial expert to develop a geospatial application, so if you're a web developer you shouldn't have any issues following this guide.

After completing this guide you will be familiar with the following concepts:

* Scaffolding your application.
* Adding a [basemap](https://docs.carto.com/carto-for-developers/key-concepts/carto-for-deck.gl/basemaps)
* Creating an [API Access Token](https://docs.carto.com/carto-for-developers/key-concepts/authentication-methods/api-access-tokens) with limited access to your data warehouse.
* Visualizing a dataset with [deck.gl](https://github.com/CartoDB/gitbook-documentation/blob/master/carto-for-developers/key-concepts/carto-for-deck.gl)
* Publishing your app

<figure><img src="https://3029946802-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FybPdpmLltPkzGFvz7m8A%2Fuploads%2F3meWJqHYuDgLEsEUjOEM%2FPublic%20App%20Diagram.png?alt=media&#x26;token=67bcf064-908e-4a89-9438-4d9cfe325f51" alt=""><figcaption><p>Architecture diagram of our public application</p></figcaption></figure>

{% hint style="info" %}
During this guide, we're using the [CARTO Data Warehouse](https://docs.carto.com/carto-user-manual/connections/carto-data-warehouse). The process explained here is also compatible with other Warehouses like BigQuery, Snowflake, Redshift, Databricks, Oracle, or Postgres. Instead of using <mark style="color:orange;">`connection=carto_dw`</mark>, you need to use <mark style="color:orange;">connection=\<your\_connection></mark>.
{% endhint %}

## Scaffolding your application

We will use [Vite](https://vitejs.dev/) to manage the tooling of our frontend application.

With NPM:

```bash
npm create vite@latest
```

Then you can choose your favorite framework (Vanilla, Vue, React, Preact, etc..) and Typescript or Javascript. In order to make this guide the most compatible as possible, we're going to use Vanilla and for the variant, we're going to select Typescript.

```bash
cd <project-name>
npm install 
npm run dev
```

After that, you should have a project up and running at <http://127.0.0.1:5174/>

Open the project you've just created in your favorite Code Editor (we recommend [Visual Studio Code](https://code.visualstudio.com/)), and let's do some cleanup in the default template provided by Vite in order to have a full empty space.

* Remove <mark style="color:blue;">src/counter.ts</mark> file.
* Replace <mark style="color:blue;">src/main.ts</mark> with the following:

```typescript
import './style.css'

document.querySelector<HTMLDivElement>('#app')!.innerHTML = ``
```

* Replace <mark style="color:blue;">src/style.css</mark> with the following:

<pre class="language-css"><code class="lang-css">body, html {
  height: 100%;
  margin: 0;
<strong>  overflow: hidden;
</strong>  padding: 0;
  position: fixed;
  width: 100%;
  font-family: Inter, sans-serif;
  font-weight: 400;
  font-size: 1rem;
}
#app {
  flex: 1 1 auto;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
</code></pre>

You will now see a completely empty page. No worries! We're going to start adding content in the following sections.

## Adding a Basemap

We're going to include a basemap in your application. As explained in the [Basemap section](https://docs.carto.com/carto-for-developers/key-concepts/carto-for-deck.gl/basemaps), you can use multiple basemaps (CARTO Basemaps, Google Maps, Amazon Location, etc...). For this guide we'll use the CARTO Basemaps, as they're available to all CARTO organizations, and do not require a third-party service.

First, we're going to install the required dependencies:

```
npm install maplibre-gl @deck.gl/core @deck.gl/carto
```

Then, create a file <mark style="color:blue;">src/map.ts</mark> with this content:

```typescript
import maplibregl from 'maplibre-gl';
import { Deck } from '@deck.gl/core';
import { BASEMAP } from '@deck.gl/carto';

export function createMap() {
  const INITIAL_VIEW_STATE = {
    latitude: 39.8097343,
    longitude: -98.5556199,
    zoom: 4,
    bearing: 0,
    pitch: 30
  };

  const deck = new Deck({
    canvas: 'deck-canvas',
    initialViewState: INITIAL_VIEW_STATE,
    controller: true,
  })

  const map = new maplibregl.Map({container: 'map', style: BASEMAP.VOYAGER, interactive: false});
  deck.setProps({
    onViewStateChange: ({viewState}) => {
      const {longitude, latitude, ...rest} = viewState;
      map.jumpTo({center: [longitude, latitude], ...rest});
    }
  });
}
```

Next, add this to <mark style="color:blue;">src/style.css</mark>:

```css
#map, canvas{
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  max-height: 100%;
}
```

And replace <mark style="color:blue;">src/main.ts</mark> with this code:

```typescript
import './style.css'
import 'maplibre-gl/dist/maplibre-gl.css';
import { createMap } from './map'

document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
  <div id="map"></div>
  <canvas id="deck-canvas"></canvas>
`
createMap()
```

## Creating an API Access Token

In order to use the CARTO APIs you need to authenticate your requests. For a public application the recommended approach is do so by creating an API Access Token. This token will be public so you need to guarantee it has limited access to the resources of your public application. You can [read more about API Access Tokens here](https://docs.carto.com/carto-for-developers/key-concepts/authentication-methods/api-access-tokens).

In this application, we're going to visualize the table: `carto-demo-data.demo_tables.populated_places.`To create an API Access Token with access to the previous table, you need to go to [CARTO Workspace](https://app.carto.com) -> Developers -> Credentials -> API Access Tokens. More info on these steps [here](https://docs.carto.com/carto-user-manual/developers/managing-credentials/api-access-tokens).

You should add the previous table as a grant:

<figure><img src="https://3029946802-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FybPdpmLltPkzGFvz7m8A%2Fuploads%2Fgit-blob-d6ab49a5812f64adcb4370457df1b2026d4f14e4%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

We also recommend limiting the token by referers URLs.

{% hint style="info" %}
The process is exactly the same if you're using another warehouse like BigQuery, Snowflake, Redshift, Databricks, Oracle, or PostgreSQL.
{% endhint %}

This API Access Token is an environment configuration, so let's add it as an environment variable.

Create a file <mark style="color:blue;">.env</mark> in the root folder:

```bash
# API Base URL (copy this from CARTO Workspace -> Developers)
VITE_API_BASE_URL=https://gcp-us-east1.api.carto.com

# Set this variable if you're using an API Access Token (public application).
# Go to app.carto.com -> Developers -> Manage API Access Tokens
VITE_API_ACCESS_TOKEN=XXX
```

{% hint style="info" %}
If you have a different region, you need to modify VITE\_API\_BASE\_URL.
{% endhint %}

## Visualizing a dataset with deck.gl

Now, we're going to visualize the populated places dataset using [deck.gl](https://github.com/CartoDB/gitbook-documentation/blob/master/carto-for-developers/key-concepts/carto-for-deck.gl#introduction) and [CARTO Maps API.](https://docs.carto.com/key-concepts/apis#maps) In this section, we're going to modify <mark style="color:blue;">src/map.ts</mark>.

Import the requirements from CARTO for deck.gl:

```typescript
import {
  BASEMAP,
  vectorTableSource,
  VectorTileLayer,
} from '@deck.gl/carto';
```

Set the credentials to connect with CARTO:

```typescript
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;
const accessToken = import.meta.env.VITE_API_ACCESS_TOKEN;
const connectionName = "carto_dw";
const cartoConfig = {apiBaseUrl, accessToken, connectionName};
```

Finally, create the source and layer to visualize both the *populated places* dataset and pass it to the Deck class:

```typescript
const demoTableSource = vectorTableSource({
  ...cartoConfig,
  tableName: 'carto-demo-data.demo_tables.populated_places'
});

const deck = new Deck({
  canvas: 'deck-canvas',
  initialViewState: INITIAL_VIEW_STATE,
  controller: true,
  layers: [
    new VectorTileLayer({
      id: 'places',
      data: demoTableSource,
      pointRadiusMinPixels: 3,
      getFillColor: [200, 0, 80],
    })
  ]
```

## Publish your application

Congratulations! You now have a working public application that will display your dataset in a map for any viewer. The application is a static website that can be deployed on your favorite web server.

Using the following command you can generate the necessary static files:

```bash
npm run build
```

Vite also provides a [guide](https://vitejs.dev/guide/static-deploy.html) to deploy a static website on different platforms like GitHub Pages, GitLab Pages, Netlify, Vercel, Firebase, etc.

## What's next?

All the code for this guide is available on [GitHub](https://github.com/CartoDB/carto-for-developers-guides/tree/master/guides/public-app).

```bash
git clone https://github.com/CartoDB/carto-for-developers-guides.git
cd carto-for-developers-guides/public-app
```

We recommend you to visit [https://github.com/CartoDB/gitbook-documentation/blob/master/carto-for-developers/key-concepts/carto-for-deck.gl](https://github.com/CartoDB/gitbook-documentation/blob/master/carto-for-developers/key-concepts/carto-for-deck.gl "mention") to learn more about the different visualizations you can create using deck.gl. There are many examples in our [gallery](https://docs.carto.com/carto-for-developers/examples) that might be useful to improve your application!
