PageSourceSearch

https://rostrum.agency/_assets/js/content-hydrate.js

js rostrum.agency collected 2026-10-06 06:43:55 UTC 2,239 bytes, 54 lines download raw bytes

1/* rostrum.agency — editable site text hydrator.
2   ----
3   Fetches /_assets/site-content.json (written by the CMS on every Content
4   save + every publish) and replaces any element with a [data-i18n="key"]
5   attribute whose key has an override. Elements without an override keep
6   the HTML default, so the site stays fully readable even if JS is off or
7   the JSON 404s.
8
9   For attributes (placeholders, aria-labels, alt text), use
10   data-i18n-attr="key|attrname" or pair both data-i18n + data-i18n-attr.
11
12   Loaded with `defer` from head.html. Pure DOM, no Alpine dependency. */
13(function () {
14  if (typeof window === 'undefined') return;
15  function apply(strings) {
16    if (!strings || typeof strings !== 'object') return;
17
18    // Element textContent overrides.
19    document.querySelectorAll('[data-i18n]').forEach(function (el) {
20      var key = el.getAttribute('data-i18n');
21      var v = strings[key];
22      if (typeof v === 'string' && v) el.textContent = v;
23    });
24
25    // Attribute overrides: data-i18n-attr="key|attr" (attr defaults to placeholder).
26    document.querySelectorAll('[data-i18n-attr]').forEach(function (el) {
27      var spec = el.getAttribute('data-i18n-attr') || '';
28      var parts = spec.split('|');
29      var key = parts[0];
30      var attr = parts[1] || 'placeholder';
31      var v = strings[key];
32      if (typeof v === 'string' && v) el.setAttribute(attr, v);
33    });
34
35    // Image overrides: data-i18n-img="key" on <img>. Replaces src + clears
36    // srcset (otherwise the browser keeps using the original responsive
37    // candidates). Optional sibling alt override via data-i18n="key.alt".
38    document.querySelectorAll('img[data-i18n-img]').forEach(function (el) {
39      var key = el.getAttribute('data-i18n-img');
40      var v = strings[key];
41      if (typeof v === 'string' && v) {
42        el.removeAttribute('srcset');
43        el.src = v;
44      }
45    });
46  }
47
48  // Fetch with cache-busting that respects HTTP cache; if the file isn't
49  // there (first deploy, CMS hasn't written one yet), silently no-op.
50  fetch('/_assets/site-content.json', { cache: 'no-cache' })
51    .then(function (r) { return r.ok ? r.json() : null; })
52    .then(apply)
53    .catch(function () { /* keep defaults */ });
54})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.