Content embedding

Put your Pubray blog, page or article listing on your landing page, e-shop or other website to enrich it with quality content & boost its SEO while having full control over the design and hosting.

Out of the box, Pubray spaces are hosted on or own domains, wrapped in Pubray's minimal and accessible experience that also acts as a mobile app. But you may also embed content on your own website, in which case Pubray acts as a so-called headless content management system (CMS).

It's a perfect way to extend your existing landing page with rich content in order to improve SEO and organic traffic. It works regardless if your website was built with one of modern no-code site builders like Carrd or created 15 years ago with a simple HTML template.

Embedding opens a way to customize your space beyond what Pubray allows with its own hosting. It's a great growth path for spaces to kickstart using Pubray hosting and then grow for custom design while still leveraging a rich set of Pubray publishing features.

Basic usage

In order to embed your space home — a list of recent articles optionally preceeded by an assigned home page — put the following script into your page's source HTML, at the place that you want it to appear:

<script defer

By adding the data-home-page attribute, you may also choose to embed a specific page along with its article listing, which allows to embed only a given section of your Pubray space:

<script defer

Next up, navigate to Space settings and paste URL of the page that includes your embed (e.g. into the Public link field. This will authorize the origin of filled URL for embedding and will link to it in space on

Hint: any website previously filled in Public link will stay authorized for embedding — you may use this to authorize multiple websites.

That's it. Once published, your updated website should now present the space appointed by data-space attribute (your-space above) — either with a list of recent posts, its assigned home page or a page specified by data-home-page attribute (your-page above).


By default, your embed is capable of navigating between the in-space content. This means that clicking links to publications from within the same space result in loading them in the same embed without a page reload and with URL always reflecting the current publication via the pub=my-publication parameter (a key for proper SEO).

This way, a single one-line embed enables you to cover a selected section or even all content from your space, allowing your visitors to view all of these publications without interruptions such as time-consuming page reloads or confusing navigation between multiple websites.

You may choose to alter this behavior by disabling the navigation:

<script defer

This allows to embed just a single page (your-page above) whose links open your default space location in a separate browser tab. It's also the only way to put multiple embeds on the same page or within the same single page app (SPA) where at most one embed may handle navigation.


Pubray embeds are fully crawlable by search engine robots (such as Googlebot) and cover following aspects of search engine optimization:

  • navigation is based on proper URLs both for navigation-enabled embeds (by patching URL with publication link picked by author) and others (by linking to or custom domain)
  • page title and description are set according to currently visible publication's metadata (and updated during navigation inside the embed)
  • canonical URL is set either to the one filled in publication's metadata, linked embed's URL or — if space isn't linked to embed anymore — an URL leading to or linked custom domain
  • RSS feed discovery is pointed to the space feed provided by Pubray


Your embed's home page presents a list of publications that were recently published and listed in space, enabled for pagination by including the Load more button (if needed). A shortened version of this list without pagination is presented when navigating to publications.

By default, recent publications are presented only if you didn't specify a home page in embed options. You may enforce showing or hiding it via data-recent="true" or data-recent="false" attribute.

In addition, both home page and sub-pages will display their own listings if present — these are also enabled for pagination.

Lazy loading

By default, Pubray embeds load content only after they've became visible in the viewport. This allows to save your visitor's network traffic as well as your billable pageviews on websites that hide the section with the embed and/or have multiple such sections.

You may disable lazy loading via data-lazy="false" attribute if needed.


The whole point of embedding content from Pubray is to have it displayed your way. By default, Pubray embed does its best to inherit styling of your website, but you have an array of options for making it look exactly the way you desire so that it blends perfectly with your design.

Built-in styling

For starters, you may decide which of Pubray embed's built-in stylesheets you'd like to include or skip:

<script defer
  data-style="base animation listing-lines"

The data-style attribute is used to specify a space-delimited list of desired stylesheets, with following sheets available:

  • base — layout of article listings + most basic rich text styles
  • animation — loading spinner + fade during navigation
  • listing-lines — line layout for listings on wide screens
  • lookup — fonts & sizing pulled for adaptive styling (more below)

Adaptive styling

Pubray embeds inherit styles that parent website provides for basic HTML elements such as headings or paragraphs. This works fine most of the time but some modern websites (and builders such as Carrd) apply styles only via specific classes while completely resetting basic styles.

For this reason, Pubray embed finds closest headings and paragraphs and copies their style into the lookup stylesheet, which it enables only when finding no basic styling (e.g. font size) for headings.

You may ensure that lookup is (or isn't) used by specifying the data-style attribute. You may then improve its results by putting sample paragraph and headings (levels 1-3) somewhere on the page (e.g. in hidden section) with the desired fonts and sizing.

Custom styling

You may apply your own styles on top of the selected built-in ones (or in place of them if you've passed an empty data-style attribute). Pubray embeds employ a well-structured, semantic markup with all the layout elements marked with a family of pubray-embed-* classes.

/* listing grid (please disable listing-lines style too) */
.pubray-embed-pub-listing-items {
  display: grid;
  grid-gap: 25px;
  grid-template-columns: repeat(3, 1fr);

/* outlook of titles and headings */
.pubray-embed :is(h1, h2, h3) {
  text-transform: uppercase;

JavaScript events

Pubray embeds fire following JavaScript events on the parent window:

  • pubray-embed:load-start — before loading content from API
  • pubray-embed:load-end — after loading & rendering content, passes content or listing in event.detail depending on what got loaded

This opens several ways to customize the end result:

  • hook your progress bar when loading starts and ends
  • refine or decorate the rendered markup after loading ends
  • render the API payload passed in event.detail on your own

Here's an sample script that takes all of these opportunities:

window.addEventListener('pubray-embed:load-start', (event) => {
  // show progress bar (

window.addEventListener('pubray-embed:load-end', (event) => {
  // hide progress bar

  // set page title using API payload
  document.title = `${event.detail.content?.pub?.title || 'Blog'} | Sample website`

  // highlight rendered code blocks (

  // adjust rendered HTML
  const backLink = document.querySelector('.pubray-embed-back a')
  if (backLink) {
    backLink.innerHTML = '≪ All articles'
You may put custom styles and scripts like the ones above (wrapped in <style>...</style> and <script>...</script> respectively) anywhere in your website's source HTML.

JavaScript API

Pubray embeds provide the PubrayEmbed global with following methods:

  • init(container, options) — create embed by passing the container + options that replace relevant script tag's data-* attributes
  • navigate(link) — ask the embed that's initialized and enabled for navigation to navigate to publication or home (by passing null)

This allows for several advanced integration scenarios:

  • present Pubray embeds within JS apps & dynamic websites
  • navigate within embed upon events from outside of it

Here's an example integration that uses all these methods:

// turn .my-embed container into Pubray embed
window.addEventListener('load', () => {
  const container = document.querySelector('.my-embed')

  PubrayEmbed.init(container, {
    space: 'my-space', // required
    homePage: 'my-page',
    navigation: false,
    lazy: true,
    recent: true,
    style: 'base anim listing-lines'

// intercept '#back' links to navigate embed back home
// (ONLY if not home already - otherwise run original action)
window.addEventListener('click', (event) => {
  if ( !== 'A') { return }
  if ('href') !== '#back') { return }
  if (!new URL(location).searchParams.get('pub')) { return }


// make '#about' links navigate embed to about page
window.addEventListener('click', (event) => {
  if ( !== 'A') { return }
  if ('href') !== '#about') { return }