From 87d2e185bf61712711c0ec3ba860f1ac8f3f926a Mon Sep 17 00:00:00 2001 From: glimps-fde <142234937+glimps-fde@users.noreply.github.com> Date: Tue, 14 Jul 2026 10:30:02 +0200 Subject: [PATCH] feat(beasties): add `data-beasties-skip` attribute to skip individual stylesheets (#335) --- packages/beasties/README.md | 14 +++++ packages/beasties/src/index.ts | 4 ++ packages/beasties/test/beasties.test.ts | 75 +++++++++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/packages/beasties/README.md b/packages/beasties/README.md index 1311a1a..d2abc28 100644 --- a/packages/beasties/README.md +++ b/packages/beasties/README.md @@ -246,6 +246,20 @@ You can estimate the contents of your viewport roughly and add a
` tag: + +```html + + + + + +``` + +Beasties will not read, inline, prune, or mutate that tag regardless of the active preload strategy. This is useful when disabling `inlineCritical` globally would sacrifice Core Web Vitals optimizations for the rest of your stylesheets. + ### Logger Custom logger interface: diff --git a/packages/beasties/src/index.ts b/packages/beasties/src/index.ts index bdfaecb..68689ba 100644 --- a/packages/beasties/src/index.ts +++ b/packages/beasties/src/index.ts @@ -305,6 +305,10 @@ export default class Beasties { * Fetch CSS content for a linked stylesheet */ private async fetchStylesheet(link: ChildNode, document: HTMLDocument): Promise { + if (link.hasAttribute('data-beasties-skip')) { + return undefined + } + const href = link.getAttribute('href') // skip filtered resources, or network resources if no filter is provided diff --git a/packages/beasties/test/beasties.test.ts b/packages/beasties/test/beasties.test.ts index d3738f4..2d2b21c 100644 --- a/packages/beasties/test/beasties.test.ts +++ b/packages/beasties/test/beasties.test.ts @@ -1086,4 +1086,79 @@ describe('beasties', () => { fs.rmSync(tmpDir, { recursive: true }) }) + + describe('data-beasties-skip', () => { + const assets: Record = { + '/styles.css': 'h1 { color: blue; }', + '/theme.css': 'body { background: red; }', + } + + function makeBeasties(opts = {}) { + const b = new Beasties({ reduceInlineStyles: false, path: '/', ...opts }) + b.readFile = filename => assets[filename.replace(/^\w:/, '').replace(/\\/g, '/')]! + return b + } + + it('leaves the skipped link tag completely untouched', async () => { + const result = await makeBeasties().process(trim` + + + + + +

Hello

+ + `) + expect(result).toContain('') + expect(result).not.toMatch(/theme\.css[^>]*onload/) + expect(result).not.toMatch(/theme\.css[^>]*rel="preload"/) + }) + + it('still processes other links normally', async () => { + const result = await makeBeasties().process(trim` + + + + + +

Hello

+ + `) + expect(result).toContain('