Continuous Scroll Setup

A continuous (or infinite) scrolling page is one where new articles are continuously loaded inline in the existing page via AJAX. Viafoura widgets fully support such types of pages, but a few special steps need to be taken to ensure that the widgets load the proper data.

Page Regions

A “page region” is a virtual page with it’s own page metadata (eg: URL, title, and description).

In a continuous scroll application, the actual web page is usually divided into section or article elements which each represent their own “web page” or “page region”. Viafoura provides functionality to tie page metadata into widgets embedded in these page regions.

By doing this, we can ensure that:

  • Attention time will be properly attributed to the correct widgets
  • Content will be correctly linked to the appropriate page metadata



Section-specific settings do not work with continuous scroll pages, all pages loaded on a continuous scroll page will inherit the settings of the actual page on which they are placed.

Workflow Overview

  1. Create new elements.
  2. Change URL.
  3. Change meta tags.
  4. Call window.vf.context.setCurrentPage(el) just passing the root element as argument.

Loading a New Page Region

When loading a new page region, you will need to tie that new region to the appropriate page metadata as well. When window.vf.context.setCurrentPage is called it will read the top-level page metadata from the page <head> and tie it to the page region passed as the first argument. For more information on page metadata see Integration with your Content.


<section id=”first-page” class=”page-region”>...</section>

<!-- second-page has been injected into the DOM by your code already -->
<section id=”second-page” class=”page-region”>
    <h1>This is the second page</h1>
    <p>Some content</p>
    <vf-conversations class="viafoura"></vf-conversations>


Once the DOM has been updated with the new page region, you can then tell viafoura to load the widget using window.vf.context.setCurrentPage.

Page Metadata from <head>

You must update page metadata in the page <head>, you will need to do so before calling setCurrentPage.



Make sure that you update all the meta tags you used initially to set the page metadata. For example, if you do not use og:url, make sure to call pushState to update the URL. If you use og:url and the <title> tag, make sure to update both before calling setCurrentPage.

function loadNewPage() {
   // Here we assume the use of vanilla page url and title tag, your needs may be different
   document.title = “new title”; // this could be replaced with setting the og:title meta tag
   history.pushState({}, '', '/some-path'); // this can be replaced with setting the og:url meta tag

   // Now that metadata is set, we can ask viafoura to load the new widget
   const newPage = document.getElementById(‘second-page’);
   window.vfQ.push(() => vf.context.setCurrentPage(newPage));



Be careful not to call setCurrentPage multiple times with elements that intersect. The function will not allow you to register the same page region twice but if two page regions intersect, then the area that is intersecting will double count the attention time.

Example Implementation

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Testing Continuous Scroll</title>
    <meta name="vf:container_id" content="testing-article-1" />
      .container {
        margin: auto;
        max-width: 800px;
      .article {
        border: 1px solid silver;
        margin-bottom: 30px;
        min-height: 2000px;
        padding: 10px;

      let counter = 1;

      function scrollEvent(event) {
        const { scrollHeight, scrollTop, clientHeight } = document.documentElement;
        if (scrollTop + clientHeight > scrollHeight - 5) {

      function createNewArticle() {

      function createElements() {
        const container = document.querySelector('.container');

        const section = document.createElement('section');
        section.className = 'article'; = `article${counter}`;

        const text = document.createElement('div');
        text.innerText = `Article ${counter} ...`;

        const containerVf = document.createElement('div');
        containerVf.className = 'viafoura';

        const widget = document.createElement('vf-conversations');

      function changeUrl() {
        history.pushState({}, '', `/testing-article-${counter}`);

      function changeMetatag() {
        const el = document.querySelector('meta[name="vf:container_id"]');
        el.content = `testing-article-${counter}`;

      function setCurrentPage() {
        const el = document.getElementById(`article${counter}`);

      window.vfQ = window.vfQ || [];
      window.vfQ.push(() => {
        const el = document.getElementById('article1');

    <script type="text/javascript" async="" src="//"></script>

  <body onscroll="scrollEvent(event)">
    <div class="container">
      <section class="article" id="article1">
        <div>Article 1...</div>
        <div class="viafoura">

    <div class="viafoura">
      <vf-tray-trigger floating="true"></vf-tray-trigger>