← Back to openlayers/openlayers

How to Deploy & Use openlayers/openlayers

OpenLayers Deployment & Usage Guide

Prerequisites

  • Node.js: Version 16.x LTS or higher (18.x recommended)
  • Package Manager: npm (included with Node.js), yarn, or pnpm
  • Browser: Modern browser with >1% global usage (Chrome, Firefox, Safari, Edge)
  • Build Tool: One of Vite, webpack, Rollup, or Parcel (Vite recommended for new projects)
  • Optional: TypeScript 4.5+ (type declarations included in ol package)

Installation

NPM Package (Recommended)

# Create new project directory
mkdir my-map-app && cd my-map-app
npm init -y

# Install OpenLayers
npm install ol

# Install development server (Vite example)
npm install --save-dev vite

CDN/No-Build Setup (Prototyping)

For quick prototyping without Node.js, use Skypack:

<!DOCTYPE html>
<html>
  <head>
    <script type="module">
      import Map from 'https://cdn.skypack.dev/ol/Map.js';
      import View from 'https://cdn.skypack.dev/ol/View.js';
      import TileLayer from 'https://cdn.skypack.dev/ol/layer/Tile.js';
      import OSM from 'https://cdn.skypack.dev/ol/source/OSM.js';
      
      new Map({
        target: 'map',
        layers: [new TileLayer({source: new OSM()})],
        view: new View({center: [0, 0], zoom: 2})
      });
    </script>
  </head>
  <body>
    <div id="map" style="width: 100%; height: 100vh;"></div>
  </body>
</html>

Configuration

Basic Map Configuration

Create main.js (or main.ts):

import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import {fromLonLat} from 'ol/proj';

const map = new Map({
  target: 'map', // DOM element ID
  layers: [
    new TileLayer({
      source: new OSM({
        // Optional: Custom tile URL (requires attribution)
        url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        attributions: '© OpenStreetMap contributors'
      })
    })
  ],
  view: new View({
    center: fromLonLat([-74.006, 40.7128]), // NYC example
    zoom: 12,
    maxZoom: 19,
    minZoom: 2
  })
});

Environment Variables (Optional)

For API keys (Mapbox, etc.), create .env:

VITE_MAPBOX_API_KEY=your_key_here

Access in code:

const mapboxKey = import.meta.env.VITE_MAPBOX_API_KEY;

TypeScript Configuration

tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"]
}

Build & Run

Vite (Recommended)

# Install
npm install --save-dev vite

# Development server
npx vite

# Production build
npx vite build
# Output: dist/ directory

Webpack

# Install dependencies
npm install --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin

# Development
npx webpack serve --mode development

# Production build
npx webpack --mode production
# Output: dist/ directory

Rollup

# Install
npm install --save-dev rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs

# Build
npx rollup -c

Parcel

# Install
npm install --save-dev parcel

# Development
npx parcel index.html

# Production
npx parcel build index.html

Deployment

OpenLayers applications are client-side only and deploy as static sites.

Build Output

Ensure your build produces:

  • index.html
  • Bundled JavaScript (e.g., assets/index-*.js)
  • Any static assets (images, fonts, data files)

Platform-Specific Deployment

Vercel (Zero-config):

npm install -g vercel
vercel --prod
# Set framework preset to "Vite" or "Other" if prompted

Netlify (Drop or CLI):

# Build first
npx vite build

# Deploy via CLI
npm install -g netlify-cli
netlify deploy --prod --dir=dist

GitHub Pages:

# Add to package.json
"homepage": "https://username.github.io/repo-name",

# Build and deploy
npx vite build
git add dist && git commit -m "Add dist"
git subtree push --prefix dist origin gh-pages

AWS S3 + CloudFront:

# Sync build output to S3 bucket
aws s3 sync dist/ s3://your-bucket-name --delete

# Invalidate CloudFront cache (if using)
aws cloudfront create-invalidation --distribution-id YOUR_ID --paths "/*"

Environment Configuration

For production builds, ensure:

  • NODE_ENV=production is set
  • Source maps disabled for public builds (optional)
  • API keys restricted to production domains

Troubleshooting

Module Resolution Errors

Error: Cannot find module 'ol/Map'

  • Solution: Ensure ol is installed: npm list ol
  • Check package.json has "type": "module" or use .mjs extension
  • For TypeScript, ensure moduleResolution is set to "node" or "bundler"

CORS Issues with Tile Layers

Error: Tiles not loading, console shows CORS errors

  • Solution: Configure tile server CORS headers, or use proxy
  • For WMS/WFS layers, ensure server supports CORS or use crossOrigin: 'anonymous':
new TileLayer({
  source: new XYZ({
    url: '...',
    crossOrigin: 'anonymous'
  })
})

Performance Issues with Large Datasets

Symptom: Slow rendering with many vector features

  • Solution:
    • Use VectorImage layer instead of Vector for static data
    • Implement clustering: new Cluster({source: vectorSource})
    • Use WebGL layers for large datasets (WebGLPointsLayer, WebGLTileLayer)
    • Enable loading strategies: strategy: bbox for WFS sources

WebGL Context Lost

Error: "WebGL context lost" in console, map disappears

  • Solution:
    • Reduce concurrent WebGL contexts (limit maps on page)
    • Handle context restoration:
map.on('webglcontextlost', (event) => {
  event.preventDefault();
  console.warn('WebGL context lost');
});

Projection Mismatches

Error: Features appear in wrong location or not at all

  • Solution:
    • Ensure view projection matches data projection
    • Use fromLonLat() for EPSG:4326 to EPSG:3857 (Web Mercator) conversion
    • Register custom projections if needed: proj4.defs('EPSG:3006', '...')

TypeScript Declaration Issues

Error: Type definitions not found or incorrect

  • Solution:
    • Ensure skipLibCheck: true in tsconfig.json
    • Import types explicitly: import type {Map} from 'ol'
    • Check ol package version matches type expectations