Performance, CSP & Accessibility
ScriptMapLibreMap loads near the viewport by default and reserves its configured dimensions during SSR. The SDK, stylesheet, Web Worker, style, and tiles stay off the network until the trigger runs.
Loading Strategies
Use the default visible trigger for maps below the fold:
<ScriptMapLibreMap
:center="[144.9631, -37.8136]"
map-style="https://tiles.openfreemap.org/styles/liberty"
/>
Load immediately when the map is the page's primary content:
<ScriptMapLibreMap
trigger="immediate"
:center="[144.9631, -37.8136]"
map-style="https://tiles.openfreemap.org/styles/liberty"
/>
Always provide a height so SSR and the first client render use the same layout:
<ScriptMapLibreMap
width="100%"
height="clamp(24rem, 60vw, 36rem)"
:center="[144.9631, -37.8136]"
map-style="https://tiles.openfreemap.org/styles/liberty"
/>
WebGL and Loading Failures
MapLibre needs WebGL and several resources referenced by the style. Use the error slot for browsers without WebGL and for network or initialization failures:
<ScriptMapLibreMap
:center="[144.9631, -37.8136]"
map-style="https://tiles.openfreemap.org/styles/liberty"
>
<template #error>
<p role="alert">
The route map is unavailable. Follow the delivery status list instead.
</p>
</template>
</ScriptMapLibreMap>
Keep essential locations, route status, and actions in normal HTML rather than relying on the canvas.
Accessibility
Give each interactive map a useful aria-label. Use the description slot for the locations, routes, or links a screen-reader user needs, and give each marker a unique aria-label.
<ScriptMapLibreMap
aria-label="Delivery route from the depot to Flinders Lane"
:center="[144.9538, -37.8151]"
map-style="https://tiles.openfreemap.org/styles/liberty"
>
<template #description>
The courier is at Docklands and is heading to Flinders Lane.
</template>
</ScriptMapLibreMap>
For a decorative map, set :interactive="false". The component disables input, removes the map from the accessibility tree, and makes its descendants inert.
Stylesheet Loading
Nuxt Scripts injects its version-pinned MapLibre stylesheet when the SDK starts loading. To bundle the stylesheet with your app instead:
export default defineNuxtConfig({
css: ['maplibre-gl/dist/maplibre-gl.css'],
})
<ScriptMapLibreMap
:center="[144.9631, -37.8136]"
:inject-styles="false"
map-style="/maps/style.json"
/>
Content Security Policy
The standard MapLibre build creates a Blob worker. Its documented CSP includes worker-src blob:, child-src blob:, and img-src data: blob: alongside the origins used by your style.
For a policy that does not allow Blob workers, self-host MapLibre's CSP build and worker:
export default defineNuxtConfig({
scripts: {
registry: {
maplibre: {
scriptInput: { src: '/maplibre-gl-csp.js' },
},
},
},
})
<ScriptMapLibreMap
:center="[144.9631, -37.8136]"
map-style="/maps/style.json"
worker-url="/maplibre-gl-csp-worker.js"
/>
Add the style, tile, sprite, glyph, and worker origins to the matching directives in your policy. See MapLibre's CSP directives for the complete requirements.