mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 09:01:03 -08:00
Every page pulled its three typefaces from fonts.googleapis.com and fonts.gstatic.com, each blog post fetched the author avatar from githubusercontent.com, and the giscus client script ran on page load. That is four outside origins contacted before a reader does anything, each costing a DNS lookup and a TLS handshake on the critical path. Fonts now come from the @fontsource packages the app already uses and are emitted as .woff2 beside the site; the avatar is a 3 KB file in public/; and the giscus embed is created by a "Show comments" button that carries the configuration as data attributes, so the script is only built when a reader asks for it. A delivered page now makes no third-party request at all, verified across the whole build. The variable Bricolage package names itself "Bricolage Grotesque Variable", so that exact name leads the display stack in the Tailwind config. The giscus test now checks the button configuration and asserts the client script is absent from the delivered HTML. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
46 lines
1.7 KiB
JavaScript
46 lines
1.7 KiB
JavaScript
import { readFile } from 'node:fs/promises';
|
|
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
const postHtmlPath = new URL('../../dist/apps/website/blog/why-external-players-help/index.html', import.meta.url);
|
|
|
|
const expectedGiscusAttributes = {
|
|
'data-repo': '4gray/iptvnator',
|
|
'data-repo-id': 'MDEwOlJlcG9zaXRvcnkyMTMxOTQ3Mzg=',
|
|
'data-category': 'Blog comments',
|
|
'data-category-id': 'DIC_kwDODLUX8s4C9eBJ',
|
|
'data-mapping': 'pathname',
|
|
'data-strict': '1',
|
|
'data-reactions-enabled': '1',
|
|
'data-emit-metadata': '0',
|
|
'data-input-position': 'bottom',
|
|
'data-theme': 'transparent_dark',
|
|
'data-lang': 'en',
|
|
};
|
|
|
|
test('published blog posts carry the Giscus configuration on a click-to-load button', async () => {
|
|
const html = await readFile(postHtmlPath, 'utf8');
|
|
const buttonMatch = html.match(/<button\b[^>]*data-giscus-loader[^>]*>/);
|
|
|
|
assert.ok(buttonMatch, 'Expected the blog post HTML to include the Giscus loader button.');
|
|
|
|
const buttonTag = buttonMatch[0];
|
|
for (const [name, value] of Object.entries(expectedGiscusAttributes)) {
|
|
assert.match(buttonTag, new RegExp(`${name}="${value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"`));
|
|
}
|
|
});
|
|
|
|
test('a blog post loads nothing from a third party before the reader asks for comments', async () => {
|
|
const html = await readFile(postHtmlPath, 'utf8');
|
|
|
|
assert.ok(
|
|
!/<script\b[^>]*\bsrc="https:\/\/giscus\.app/.test(html),
|
|
'The giscus client must not be a script tag in the delivered HTML — it is created on click.'
|
|
);
|
|
assert.match(
|
|
html,
|
|
/data-script-src="https:\/\/giscus\.app\/client\.js"/,
|
|
'The loader button must carry the giscus client URL for its click handler.'
|
|
);
|
|
});
|