Skip to main content
Guides

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:

nuxt.config.ts
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:

nuxt.config.ts
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.

Was this page helpful?