> ## Documentation Index
> Fetch the complete documentation index at: https://docs.obvlo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Embed API

> Drop a single Obvlo guide into a page you already control, as an HTML fragment served from the Obvlo edge.

The Embed API returns one Obvlo page as an **HTML fragment** — no `<html>`, no header, no footer — so you can place it inside a page your own site already renders. Use it when the surrounding page is yours and only the guide content comes from Obvlo.

If you want Obvlo to serve whole pages under your domain instead, use [Reverse proxy](/microsite/reverse-proxy) or [Dynamic serving](/microsite/ssr-proxy).

<Note>
  Embedding is enabled per domain by Obvlo. Ask your account contact to switch your domain to embed
  mode — the portal's **Integration** tab then generates these snippets pre-filled with your own
  organisation and site ids.
</Note>

## Choose client-side or server-side

This is an SEO decision, not a preference.

|                     | Client-side script                                     | Server-side include                                               |
| ------------------- | ------------------------------------------------------ | ----------------------------------------------------------------- |
| How it arrives      | The browser fetches the fragment after the page loads  | Your server fetches the fragment and inlines it before responding |
| What a crawler sees | An empty container, unless the crawler runs JavaScript | The full guide, in the first response                             |
| Setup               | Paste two tags into a template                         | A few lines in your server or application code                    |
| Use it when         | The guide is supplementary content                     | **The guide is the reason the page should rank**                  |

Anything you want indexed should use the server-side include.

## Client-side script

Paste the container and the loader into your page template. The loader reads its configuration from the container's `data-obvlo-*` attributes.

```html theme={null}
<div data-obvlo-embed
     data-obvlo-org="{orgId}"
     data-obvlo-site="{siteId}"
     data-obvlo-path="/paris"
     data-obvlo-base="/local-guides">
  <!-- Optional fallback: shown until the guide loads, and kept if it cannot be loaded. -->
</div>
<script src="https://sites.obvlo.com/api/embed/loader.js" async></script>
```

| Attribute           | Meaning                                                                                                                                   |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `data-obvlo-org`    | Your Obvlo organisation id.                                                                                                               |
| `data-obvlo-site`   | The Obvlo site the page belongs to.                                                                                                       |
| `data-obvlo-path`   | The page's path **within the Obvlo site** — the page hierarchy, not the URL on your domain.                                               |
| `data-obvlo-base`   | Optional. A path prefix on **your** domain. Set it and links inside the fragment stay on your site; omit it and they point back at Obvlo. |
| `data-obvlo-locale` | Optional. A configured language code. Defaults to the site's default language.                                                            |

Anything you put inside the container is a fallback: it stays on screen until the guide loads, and stays permanently if the fetch fails. The loader only ever writes on success, so a bad network never blanks the section.

## Server-side include

Your server fetches the fragment while rendering, so the guide is in the HTML the crawler receives.

```php theme={null}
<?php
// Obvlo embed — server-side include. Fetched at render time, so the guide is in the HTML
// the crawler receives. Falls back to an empty string: never a PHP error, never a 404 body.
$obvlo_url = 'https://sites.obvlo.com/api/embed/content?org={orgId}&site={siteId}&path=%2Fparis&base=%2Flocal-guides';
$obvlo_ctx = stream_context_create([
  'http' => ['timeout' => 5, 'ignore_errors' => true],
]);
$obvlo_html = @file_get_contents($obvlo_url, false, $obvlo_ctx);
$obvlo_ok = isset($http_response_header[0])
  && strpos($http_response_header[0], ' 200 ') !== false;

echo ($obvlo_ok && $obvlo_html !== false) ? $obvlo_html : '';
?>
```

Three properties matter more than the language you write it in, and every version Obvlo generates has all three:

* **A timeout.** Obvlo must never hold up your own response.
* **A status check.** A 404 body is an error page, not content — never inline it.
* **An empty-string fallback.** The page renders without the guide rather than erroring.

The portal also generates NGINX `ssi` and Node versions of the same include. Open the **Integration** tab for your site and pick the flavour you need.

### The endpoint

```text theme={null}
https://sites.obvlo.com/api/embed/content?org=…&site=…&path=…&base=…
```

| Parameter | Required | Meaning                                                                  |
| --------- | -------- | ------------------------------------------------------------------------ |
| `org`     | Yes      | Your Obvlo organisation id.                                              |
| `site`    | Yes      | The Obvlo site id.                                                       |
| `path`    | Yes      | URL-encoded page path within the site, e.g. `%2Fparis`.                  |
| `base`    | No       | URL-encoded path prefix on your domain, so internal links stay with you. |
| `locale`  | No       | A configured language code.                                              |

The response is an HTML fragment with a `text/html` content type. It carries no `<html>`, `<head>`, `<header>` or `<footer>` — those stay yours.

<Warning>
  The embed endpoint serves the **published** version of a page only. A page that has not been
  published yet returns a 404, which your include should treat as "render without the guide".
</Warning>

## Styling

The fragment ships with the styles it needs, scoped so they do not leak into your page. Your own stylesheet still applies to the surrounding layout, so give the container the width and spacing you want the guide to occupy and let the fragment fill it.

## Troubleshooting

### The container stays empty

* Check the browser's network tab for the `/api/embed/content` request. A 404 means the `org`, `site` or `path` does not match a published page.
* Confirm `data-obvlo-path` is the path **inside the Obvlo site**, not the URL on your domain.
* Confirm the page is published, not just built.

### Links inside the guide leave my site

Set `data-obvlo-base` (or the `base` query parameter) to the path prefix where the guides live on your domain.

### The guide is not appearing in search results

You are almost certainly on the client-side script. Move to the server-side include — a crawler that does not execute JavaScript sees only your fallback.

### Check the endpoint directly

```bash theme={null}
curl -sS "https://sites.obvlo.com/api/embed/content?org={orgId}&site={siteId}&path=%2Fparis" | head
```

## Related pages

* [Deployment modes](/microsite/deployment-modes)
* [Reverse proxy](/microsite/reverse-proxy)
* [Dynamic serving](/microsite/ssr-proxy)
* [Microsite overview](/microsite/overview)
