2

Our website uses JS to do partial page hydration to avoid downloading the entire page when navigating within the website. We have been getting reports from Safari browser users that when they click a nav link, they loose all the content (but the header and footer are still there).

All pages have a full static html version (for when they are landed on) and a json file with the content specific to that page.

Our JS script intercepts internal links, fetches the appropriate JSON file then parses the JSON data inserting the appropriate content in its correct spot. We are using the older style XMLHttpRequest rather than fetch to assist older technology. The system works on all the browsers we have access to (mostly Windows and Android based).

The reports from folks seem to be older versions 14 & 15, not the latest. But our customers are not always computer savvy, so haven't been able to get any detailed info.

Our Javascript is below. The process gets called as part of a page wide event propagation script on all A links:

// what is left should be used for page hydration
else {

    // determine target page name, then convert to json file name
    const tpath = url.pathname;
    const pgpath = tpath.replace('.htm', '.json');
    const pgurl = bspgurl + pgpath;

    // trigger page fetch and hydration
    getNewPage(pgurl, tpath);
  }

The getNewPage:

// fetch json from server, hydrate page with new content
function getNewPage(url, tpath) {
  const xmlhttp = new XMLHttpRequest();

  xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      // scroll to top of page
      window.scroll({
        top: 0,
        left: 0,
        behavior: 'instant',
      });
      // insert new page content
      const myArr = JSON.parse(this.responseText);
      putNewPage(myArr);
      // update browser history
      saveToHstry(myArr, tpath);

    }
  };
  xmlhttp.open('GET', url, true);
  xmlhttp.send();
}

The putNewPage

// hydrate page with new content
function putNewPage(data) {
  const m = document.getElementsByTagName('meta');
  const l = document.getElementsByTagName('link');
  const p = document.getElementsByTagName('input');
  for (let i = 0; i < data.length; i++) {
    switch (data[i].fncn) {
      case 'body':
        var bdy = document.getElementsByTagName('body');
        bdy[0].setAttribute('id', data[i].cntnt);
        pgType = data[i].cntnt;
        break;
      case 'bkgnd':
        document.body.className = '';
        document.body.classList.add(data[i].cntnt);
        break;
      case 'title':
        document.title = data[i].cntnt;
        break;
      case 'metan':
        for (var j = 0; j < m.length; j++) {
          if (m[j].getAttribute('name') === data[i].trgt) {
            m[j].setAttribute('content', data[i].cntnt);
          }
        }
        break;
      case 'metap':
        for (var j = 0; j < m.length; j++) {
          if (m[j].getAttribute('property') === data[i].trgt) {
            m[j].setAttribute('content', data[i].cntnt);
          }
        }
        break;
      case 'link':
        for (let k = 0; k < l.length; k++) {
          if (l[k].getAttribute('rel') === data[i].trgt) {
            l[k].setAttribute('href', data[i].cntnt);
          }
        }
        break;
      case 'id':
        $(data[i].trgt).innerHTML = data[i].cntnt;
        break;
      case 'input':
        for (let f = 0; f < p.length; f++) {
          if (p[f].getAttribute('name') === data[i].trgt) {
            p[f].setAttribute('value', data[i].cntnt);
          }
        }
        break;
      case 'js':
        window[data[i].trgt] = data[i].cntnt;
        break;
    }
  }
}

The website pages are all pre-rendered and saved on a CDN.

As requested a sample of the hydration json file. The page layout has 10 divs, of which some pages have content is all ten, other pages only a couple of divs. The feedback we get seems to indicate that the content is stripped out as expected, but not replaced.

[
{ 
  "fncn": "body",
  "trgt": "body",
  "cntnt": "gen" 
},
{ 
  "fncn": "bkgnd",
  "trgt": "bkgnd",
  "cntnt": "jigsaw" 
},
{ 
    "fncn": "title",
    "trgt": "title",
    "cntnt": "Travel Agent booking information" 
}, 
{ 
    "fncn": "metan",
    "trgt": "description",
    "cntnt": "Information for travel agencies wanting to seel Pedalers tours"
}, 
{ 
    "fncn": "metan",
    "trgt": "image",
    "cntnt": "https:\/\/pedalers.travel\/img\/ppg-logo-vrt.png"
}, 
{ 
    "fncn": "metap",
    "trgt": "og:title",
    "cntnt": "Travel Agent booking information"
}, 
{ 
    "fncn": "metap",
    "trgt": "og:description",
    "cntnt": "Information for travel agencies wanting to seel Pedalers tours"
}, 
{ 
    "fncn": "metap",
    "trgt": "og:image",
    "cntnt": "https:\/\/pedalers.travel\/img\/ppg-logo-vrt.png"
}, 
{ 
    "fncn": "metap",
    "trgt": "og:url",
    "cntnt": "https:\/\/pedalers.travel\/travel-agency.htm"
}, 
{ 
    "fncn": "metan",
    "trgt": "theme-color",
    "cntnt": "#212121"
},
{ 
    "fncn": "link",
    "trgt": "canonical",
    "cntnt": "https:\/\/pedalers.travel\/travel-agency.htm"
}, 
{ 
    "fncn": "id",
    "trgt": "div1",
    "cntnt": "<div class=\"nosplsh nsblk\">\r\n  <h1>Welcome Travel Agents<\/h1>\r\n  <p class=\"smlhdr\">Pedalers is happy to work with Travel Professionals<\/p>\r\n<\/div>"
}, 
{ 
    "fncn": "id",
    "trgt": "div2",
    "cntnt": "<div class=\"text twothirds\">\r\n<h2>Book With Pedalers\r\n\r\n<\/h2><p>Thanks for visiting our website in search of great adventure vacations for your clients.  Pedalers works together with our Travel Industry partners, offering a multi-tiered compensation plan for travel agencies that market and specialize in adventure travel.  For complete details, please fill out our Travel Agency Registration Form.  We will be back in touch promptly.<\/p>\r\n<p><a href=\"https:\/\/secure.pedalers.travel\/tvl-agency-registration.php\" class=\"btn bgrn\">Agency Sign Up<\/a><\/p>\r\n<\/div>"
}, 
{ 
    "fncn": "id",
    "trgt": "div3",
    "cntnt": ""
}, 
{ 
    "fncn": "id",
    "trgt": "div4",
    "cntnt": ""
}, 
{ 
    "fncn": "id",
    "trgt": "div5",
    "cntnt": ""
}, 
{ 
    "fncn": "id",
    "trgt": "div6",
    "cntnt": ""
}, 
{ 
    "fncn": "id",
    "trgt": "div7",
    "cntnt": ""
}, 
{ 
    "fncn": "id",
    "trgt": "div8",
    "cntnt": ""
}, 
{ 
    "fncn": "id",
    "trgt": "div9",
    "cntnt": ""
}, 
{ 
    "fncn": "id",
    "trgt": "div10",
    "cntnt": ""
}, 
{ 
    "fncn": "input",
    "trgt": "source",
    "cntnt": "travel-agency.htm"
},
{ 
  "fncn": "js",
  "trgt": "tourid",
  "cntnt": "0" 
},
{ 
  "fncn": "js",
  "trgt": "pageid",
  "cntnt": "69" 
},
{ 
  "fncn": "js",
  "trgt": "country",
  "cntnt": "none" 
}
]
Tom
  • 2,928
  • 4
  • 28
  • 36
  • forgive me if I am going to say a stupid thing, but in this line : `const pgpath = tpath.replace('.htm', '.json');` is the code `.htm` correct instead of : `.html` ? – Lvcaa Feb 09 '23 at 09:39
  • @lvcaa, yes it is correct, we use .htm instead of .html – Tom Feb 09 '23 at 09:41
  • What is `pgType`? – qrsngky Feb 26 '23 at 02:57
  • @qrsngky - `pgType` is a js variable used by other functions in the script to distinguish different page types such a general info page vs a product page. It was defined on the initial load and gets updated each time the content is hydrated. – Tom Feb 26 '23 at 03:21

1 Answers1

1

Edit:

I've looked at the website itself and tested it in Safari Version 16.2 (18614.3.7.1.5).

I don't see any errors in the browser console but I can see the missing content problem as you can see in this recording: https://share.cleanshot.com/6vKchgKz (For future reference if the video gets deleted - The video shows the design differences between safari and firefox).

The content is actually there but the parallax/sliding images feature is not compatible with safari and leads to content being "hidden" because other slides are "above" the content you want to slide in.

Check out this recording where I set the z-index after page load: https://share.cleanshot.com/22ZTCJ54 (For future reference: The video shows that setting z-index to 20 on #div6 makes the element visible).

posixpascal
  • 3,031
  • 3
  • 25
  • 44
  • it is an alias for getElementbyId. I will add a section from the json later (am not at my office on the weekend). – Tom Feb 25 '23 at 14:08
  • As per your request I have added one of the smaller json files. The main page layout has ten main divs and some pages have content in each, other simpler pages might have content in only one. – Tom Feb 26 '23 at 01:46
  • Hey, I've updated the comment. Looks like a z-index problem related to the slides. The JSON-update-logic runs through without problems on my safari but content was still "missing". Let me know if this solves your problem or else I'll look for more. – posixpascal Feb 26 '23 at 14:39
  • The navigation hydration was temporarily removed, until we can sort out the issue, so wasn't there when you visited. Don't want to chase away potential guests. The issue was that when navigating to a new page the old page content was removed but not replaced with the new page content. Those reporting the issue were using Safari 14 and 15. Your mention of the homepage z-index issue is the first we heard of that. Seems that Safari is on its way to be the new Internet Explorer. – Tom Feb 27 '23 at 06:12
  • Can you setup a private test-site so I that I can test the navigation? – posixpascal Feb 27 '23 at 08:00
  • [link](https://pedalers.travel/test-tours.htm) is using the older JS file with navigation hydration. It also use island hydration to update 'scheduled' dates. Unfortunately I have no access to Apple computers to test with. – Tom Feb 27 '23 at 08:58