Cài đặt
MapsLibVN có bốn gói: @mapslibvn/core (client REST thuần), @mapslibvn/web (bản đồ MapLibre + web
component), @mapslibvn/react và @mapslibvn/react-native. Trang này chỉ nói về cài đặt; cách
dùng nằm ở Bản đồ web và Tìm kiếm & autocomplete.
1. Bốn cách nhúng
Phần tiêu đề “1. Bốn cách nhúng”Không cần build, không cần npm. Bản UMD đã đóng gói sẵn maplibre-gl và pmtiles, phơi ra global
MapsLibVN, và tự đăng ký web component <mapslibvn-autocomplete>.
<link rel="stylesheet" href="https://mapslibvn-docs.pages.dev/sdk/mapslibvn.css" /><script src="https://mapslibvn-docs.pages.dev/sdk/mapslibvn.umd.js"></script>
<div id="map" style="height:400px"></div><mapslibvn-autocomplete id="ac" api-key="mlv_live_…" api-base="https://api.ai-solutions.io.vn"></mapslibvn-autocomplete>
<script> const map = MapsLibVN.createMap({ container: 'map', apiKey: 'mlv_live_…', apiBase: 'https://api.ai-solutions.io.vn', center: [106.70, 10.776], zoom: 13, }); // Gán map để autocomplete dùng cùng Places client/poiSources và lấy tâm làm `near`. document.getElementById('ac').map = map;</script>Global MapsLibVN gồm: createMap, maplibregl, createClient, MapsLibVNError,
attributionHtml, attributionText, applyLanguage, nameExpression, MapsLibVNAutocomplete,
defineAutocomplete.
mapslibvn.css là CSS của MapLibre đóng gói kèm — thiếu nó thì bản đồ hiện sai (điều khiển chồng
lên nhau, popup không có khung).
MapLibre 6 chạy worker ESM riêng. Khi tự host SDK, phải đặt maplibre-gl-worker.mjs và
maplibre-gl-shared.mjs cạnh mapslibvn.umd.js; thư mục /sdk/ phát hành sẵn đã chứa đủ ba file.
Nếu bạn tự host SDK, hãy thay tên miền: cả mapslibvn-docs.pages.dev lẫn api.ai-solutions.io.vn
đều là endpoint tạm thời của giai đoạn nội bộ. Xem Tự host.
pnpm add @mapslibvn/web maplibre-glmaplibre-gl@^6.4.1 là peer dependency — bạn phải tự cài. Bản ESM không gộp maplibre, nên phải
truyền vào qua deps:
import 'maplibre-gl/dist/maplibre-gl.css';import * as maplibregl from 'maplibre-gl';import { createMap, defineAutocomplete } from '@mapslibvn/web';
defineAutocomplete(); // bản ESM KHÔNG tự đăng ký <mapslibvn-autocomplete>
const map = createMap( { container: 'map', apiKey: 'mlv_live_…', apiBase: 'https://api.ai-solutions.io.vn', }, { maplibre: maplibregl },);Bỏ tham số thứ hai thì createMap tìm globalThis.maplibregl; không thấy sẽ ném
Error: Cần maplibre-gl: import maplibre-gl hoặc dùng bản UMD @mapslibvn/web/umd.
Hai khác biệt so với bản UMD: bạn tự import CSS của MapLibre, và bạn tự gọi defineAutocomplete().
Còn một bước bắt buộc cho bản build: trỏ worker của MapLibre về thư mục tĩnh của bạn — xem mục 2 “Worker của MapLibre khi dùng bundler” bên dưới. Bỏ bước này thì bản build ra bản đồ trống.
pnpm add @mapslibvn/react maplibre-glPeer dependencies: maplibre-gl@^6.4.1 và react>=18. Gói tự import maplibre-gl bên trong, bạn
không cần truyền deps.
import 'maplibre-gl/dist/maplibre-gl.css';import { MapsLibVNMap, Marker } from '@mapslibvn/react';
export function BanDo() { return ( <MapsLibVNMap apiKey="mlv_live_…" apiBase="https://api.ai-solutions.io.vn" center={[106.7, 10.776]} zoom={13} containerStyle={{ height: 400 }} onLoad={(map) => console.log('đã tải', map.gl.getZoom())} > <Marker lng={106.6981} lat={10.7725} popupHtml="<b>Chợ Bến Thành</b>" /> </MapsLibVNMap> );}Vì gói tự import 'maplibre-gl', bundler của bạn sẽ gộp maplibre vào chunk của ứng dụng — nên vẫn
cần bước worker ở mục 2 “Worker của MapLibre khi dùng bundler” bên dưới.
Chi tiết props và hook: React.
App iOS/Android dùng @mapslibvn/react-native, bọc
@maplibre/maplibre-react-native với cùng API như
bản React.
npx expo install @maplibre/maplibre-react-native expo-applicationnpm install <đường dẫn tarball @mapslibvn/react-native>Khác với web ở bốn điểm: cần khoá kind mobile (không kiểm origin), cần New Architecture,
không chạy trên Expo Go, và tarball của gói này tự chứa @mapslibvn/core nên chỉ cần cài
một file. Lệnh pnpm example:rn trong repo dựng sẵn cả quy trình.
Toàn bộ hướng dẫn: React Native.
2. Worker của MapLibre khi dùng bundler
Phần tiêu đề “2. Worker của MapLibre khi dùng bundler”Chỉ liên quan tới hai cách nhúng qua bundler (npm (ESM) và React). Bản UMD /sdk/ đã kèm sẵn
hai file worker nên không phải làm gì.
MapLibre 6 chạy worker ESM riêng và tự suy URL của nó lúc chạy:
new URL('./maplibre-gl-worker.mjs', import.meta.url)import.meta.url ở đây là URL của chunk mà bundler đã gộp maplibre vào. Vite, webpack, Rollup và
Parcel đều gộp maplibre vào chunk của bạn nhưng không phát ra hai file worker cạnh chunk đó, nên
trình duyệt đi xin maplibre-gl-worker.mjs trong thư mục chunk và nhận 404.
Cách xử lý
Phần tiêu đề “Cách xử lý”Copy cả hai file vào thư mục tĩnh của ứng dụng, rồi trỏ maplibre vào đó trước khi tạo map:
cp node_modules/maplibre-gl/dist/maplibre-gl-worker.mjs \ node_modules/maplibre-gl/dist/maplibre-gl-shared.mjs \ public/import * as maplibregl from 'maplibre-gl';
maplibregl.setWorkerUrl('/maplibre-gl-worker.mjs'); // phải gọi TRƯỚC khi tạo mapỞ React, gọi setWorkerUrl một lần tại điểm vào ứng dụng, cùng chỗ import CSS của MapLibre.
Phải đủ cả hai file và cạnh nhau: maplibre-gl-worker.mjs có import './maplibre-gl-shared.mjs',
nên thiếu file shared thì worker tải được (200) rồi chết ngay với net::ERR_ABORTED và bản đồ vẫn trống.
Nên gắn bước copy vào script build để không lệch phiên bản mỗi lần nâng maplibre-gl:
{ "scripts": { "prebuild": "cp node_modules/maplibre-gl/dist/maplibre-gl-worker.mjs node_modules/maplibre-gl/dist/maplibre-gl-shared.mjs public/" }}maplibre-gl@6 chỉ cung cấp setWorkerUrl(url) và getWorkerUrl(), không có API truyền lớp Worker,
nên phục vụ hai file tĩnh là đường chắc chắn đúng với mọi bundler. Site này cũng làm y như vậy: bản UMD
đặt hai file cạnh mapslibvn.umd.js trong /sdk/, còn trang React demo copy chúng vào
thư mục asset của bản build.
3. Yêu cầu
Phần tiêu đề “3. Yêu cầu”| Môi trường | Tối thiểu |
|---|---|
| Trình duyệt | 2 bản mới nhất của Chrome, Edge, Firefox, Safari; iOS Safari 16+ |
maplibre-gl (bản ESM và React) |
^6.4.1, peer dependency; cần WebGL2 — bản UMD đã gộp sẵn |
React (@mapslibvn/react) |
>=18 |
React Native (@mapslibvn/react-native) |
RN >=0.80 New Architecture, React >=19.1, @maplibre/maplibre-react-native ^11.3.0, Android API 23, Expo SDK 54+ |
| Node (chỉ khi dựng SDK từ repo) | 22+, pnpm 9.15 |
| Khoá API | kind web cho trang web, kind mobile cho app — xem Khoá API |
Bản đồ dùng WebGL2. Máy không có WebGL2 thì MapLibre không khởi tạo được và createMap ném lỗi.
4. Cài từ tarball để kiểm thử bản source
Phần tiêu đề “4. Cài từ tarball để kiểm thử bản source”Bản npm là cách cài mặc định. Nếu cần kiểm thử thay đổi local trước lần phát hành tiếp theo,
pnpm pack không nhận --filter, nên phải chạy trong thư mục gói:
pnpm --filter @mapslibvn/core --filter @mapslibvn/web buildcd packages/core && pnpm pack --pack-destination /tmp/mlv && cd -cd packages/web && pnpm pack --pack-destination /tmp/mlv && cd -
# trong dự án của bạn# tên file mang version trong package.json, ví dụ mapslibvn-core-0.7.1.tgz — `ls /tmp/mlv` để lấynpm install /tmp/mlv/mapslibvn-core-*.tgz /tmp/mlv/mapslibvn-web-*.tgz maplibre-glKhi cài tarball Web local, npm có thể tự tải @mapslibvn/core cùng version từ registry. Muốn kiểm thử
đồng thời source local của cả hai thì cài cả hai tarball như ví dụ. Dùng React local tương tự với
ba tarball core, web, react. Riêng @mapslibvn/react-native gộp sẵn core vào dist, chỉ
cần một tarball.
5. Kiểm tra đã cài đúng
Phần tiêu đề “5. Kiểm tra đã cài đúng”const map = MapsLibVN.createMap({ container: 'map', apiKey: 'mlv_live_…', apiBase: '…' });
map.on('load', () => console.log('OK — style và tiles đã tải'));map.gl.on('error', (e) => console.error('LỖI:', e.error?.message));Ba dấu hiệu cài đúng:
- Sự kiện
loadchạy — style đọc được từ/v1/styles/light.json. - Điều khiển ghi nguồn hiện ở góc dưới phải, có chữ
OpenStreetMap. Ghi nguồn luôn hiện và chỉ có tuỳ chọncompactAttributionđể thu gọn — xem Giấy phép & ghi nguồn. - Trên tab Network, các request tiles trả
206 Partial Content(hoặc200): PMTiles đọc bằng HTTP Range trực tiếp từ R2.
6. Lỗi hay gặp
Phần tiêu đề “6. Lỗi hay gặp”| Hiện tượng | Nguyên nhân | Cách xử lý |
|---|---|---|
Không có bản đồ, console báo 403 với origin_not_allowed |
Khoá kind web nhưng origin của trang không nằm trong allowed_origins |
Xin bổ sung origin, hoặc thử bằng khoá demo trên localhost — xem Khoá API |
401 missing_key / 401 invalid_key |
Chưa truyền khoá, hoặc khoá đã bị thu hồi | Truyền qua header X-Api-Key hoặc ?key= |
| Bản đồ hiện nhưng điều khiển vỡ, popup không có khung | Thiếu CSS | Bản UMD: thêm mapslibvn.css. Bản ESM: import 'maplibre-gl/dist/maplibre-gl.css' |
Bản đồ trống trơn chỉ ở bản build, dev server vẫn tốt; Network có maplibre-gl-worker.mjs 404 trong khi style JSON và pmtiles đều 200 |
Bundler gộp maplibre vào chunk của bạn nhưng không phát ra file worker cạnh chunk đó | Copy maplibre-gl-worker.mjs + maplibre-gl-shared.mjs vào thư mục tĩnh rồi gọi setWorkerUrl — mục 2 |
Error: Cần maplibre-gl… |
Bản ESM thiếu peer maplibre-gl, hoặc quên truyền { maplibre: maplibregl } |
Cài maplibre-gl@^6.4.1 và truyền vào createMap |
<mapslibvn-autocomplete> không hiện gì |
Bản ESM chưa gọi defineAutocomplete() |
Gọi một lần lúc khởi động ứng dụng |
| Ô autocomplete có nhưng không gợi ý | Thiếu api-key hoặc api-base, hoặc gõ dưới 2 ký tự |
Đặt đủ hai thuộc tính; component chỉ gọi API từ 2 ký tự trở lên |
| Khung bản đồ cao 0px | Thẻ chứa map không có chiều cao | Đặt height cho #map (hoặc containerStyle ở React) |
Đọc thêm: Khoá API để lấy khoá đúng loại, Nhúng thử trang của bạn để chạy một trang HTML trắng trong 2 phút, Bắt đầu 5 phút cho đường nhanh nhất.