Skip to content

Embed Your First Pane

This guide walks through every line needed to embed a live cloud data pane in a web page. By the end, you will have a working HTML page that displays EC2 instances from your AWS account.

What you need:

The complete example

status.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Infrastructure Status</title>
</head>
<body>

    <h1>EC2 Instances</h1>

    <!-- 1. Configuration -->
    <script>
        window.lpEmbed = {
            apiBase:   'https://api.lightpane.io',
            accessKey: 'csl_em_YOUR_ACCESS_KEY_HERE'
        };
    </script>

    <!-- 2. Loader script — pulls in everything else -->
    <script src="https://lightpane.io/embed/lp.js"></script>

    <!-- 3. Target div — the pane renders here -->
    <div data-lp-service="ec2"
         data-lp-region="eu-west-2"
         data-lp-attributes="name,instance_id,instance_type,state,private_ip"></div>

</body>
</html>

Replace csl_em_YOUR_ACCESS_KEY_HERE with your embed key. Save the file and open it in a browser.

What each part does

1. Configuration

<script>
    window.lpEmbed = {
        apiBase:   'https://api.lightpane.io',
        accessKey: 'csl_em_YOUR_ACCESS_KEY_HERE'
    };
</script>

Set this once per page, before the loader script. apiBase is the LightPane API endpoint; accessKey authenticates your requests. Optional fields you can add here:

Field Purpose
region Default region for every pane on the page (each pane can override via data-lp-region).
useSession Set to true to authenticate via session cookie instead of access key (Hosted Lens flow).
deferAutoRun Set to true to suppress the automatic render on DOMContentLoaded — call window.lpEmbedRun() yourself when ready.

2. Loader script

<script src="https://lightpane.io/embed/lp.js"></script>

lp.js is a tiny loader. It injects the underlying CSS and JS modules (lp-fetch.js, lp-render.js, lp-pane.js, lp-chart.js, sd-embed.js, sd-embed.css) in the right order, then scans the page for data-lp-service targets and renders them. You can include it anywhere in the document — <head>, mid-<body>, or at the end. It picks up panes that exist at DOMContentLoaded; panes added later require a call to window.lpEmbedRun() to render.

3. Target div

<div data-lp-service="ec2"
     data-lp-region="eu-west-2"
     data-lp-attributes="name,instance_id,instance_type,state,private_ip"></div>

Every pane on the page is one <div> with data-lp-* attributes. The full set:

Attribute Purpose
data-lp-service Required. The service to discover. See the Service Catalogue for every supported service.
data-lp-region Cloud region to query. Overrides window.lpEmbed.region.
data-lp-attributes Comma-separated list of attribute IDs to render. Omit to show the service's default columns.
data-lp-account Specific binding alias (e.g. acme-prod-eu) or canonical address (aws:123456789012). Omit to query every binding your key allows.
data-lp-match Substring match against binding aliases — picks every account whose alias contains the string. Mutually exclusive with data-lp-account.
data-lp-label Display title override (e.g. "Production EC2" instead of the default service label).
data-lp-render Render mode override. stacked shows one card per matched binding instead of the default merged table.
data-lp-source Set to mock to render fixture data instead of querying your account — useful for layout previews without a live API hit.

Multiple <div>s on one page work as expected — each pane renders independently, and lp.js batches the API calls.

Troubleshooting

CORS error in browser console

Access to fetch at 'https://api.lightpane.io/...' has been blocked by CORS policy

Check that the domain you are serving the page from is listed in the allowed_origins constraint on your access key. If you are testing locally, add http://localhost:8080 (or your local port) to allowed origins.

401 Unauthorized

The access key is invalid, expired, or revoked. Check that:

  • The key was copied correctly (no extra spaces or line breaks)
  • The key has not expired — check the expiry in Access Keys on your account
  • The key has not been revoked

403 Forbidden

A constraint check failed. The API response body contains the specific reason:

Error message Cause Fix
"Origin not permitted for this token" The page domain is not in allowed_origins Add the domain to allowed origins on the key
"IP address not permitted for this token" The client IP is not in allowed_ips Update the allowed IPs
"Referer header required for this token" require_referer is enabled but no Referer header was sent Serve the page from a web server (not file://)
"Service X not permitted by this token" The key does not include this service Create a new key with the service included, or use a key scoped to all services

Pane renders but shows no data

The API returned zero resources. This is normal if:

  • The region has no resources of that type (e.g. no EC2 instances in us-west-1)
  • The cloud account has no resources of that type

Check the browser network tab — the API response will show "resources": [] with "success": true.

Pane does not render at all

Check that:

  • data-lp-service is set on at least one element on the page
  • window.lpEmbed.accessKey is set before lp.js loads (script order matters)
  • lp.js and its sub-modules are not blocked by Content Security Policy — see the next section
  • The browser console has no errors from lp-embed: warnings

Content Security Policy

Pages with strict CSP need to allow LightPane's hosts. The minimum policy:

script-src  'self' https://lightpane.io 'unsafe-inline';
style-src   'self' https://lightpane.io 'unsafe-inline';
connect-src 'self' https://api.lightpane.io;

The 'unsafe-inline' requirements come from the inline window.lpEmbed = {...} block and the runtime style injection in sd-embed.css. If your policy uses nonces, add a matching nonce to the inline script.

What next