Created
June 19, 2024 20:29
-
-
Save pauleveritt/8954fa66f43ef3fa604928a25eac2507 to your computer and use it in GitHub Desktop.
11ty TSX subcomponents and shortcakes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Summary: TSX subcomponents don't have access to shortcodes. The | |
this.context.shortcodes.css() function runs, but doesn't put | |
its content into the bundle. | |
*/ | |
export type Context = { | |
// The "this" value has a "context" managed by Preact. | |
// In eleventyConfig "compile", we call Preact's "render" | |
// function. This argument can take a second value which | |
// is then assigned to "this.context" in subcomponents. | |
// Note: The layout itself doesn't have this.context from | |
// Preact because 11ty re-binds "this". | |
shortcodes: { | |
css: (content: string) => void; | |
}; | |
}; | |
export type ThisHeading = { | |
context: Context; | |
}; | |
function Heading(this: ThisHeading, data: any) { | |
// This subcomponent should shove CSS into the bundle. However, | |
// it appears to be the wrong function. | |
this.context.shortcodes.css(".xyz {font-weight: bold}"); | |
return <h2>The Heading</h2>; | |
} | |
export type RenderData = { | |
getBundle(name: string): string; | |
}; | |
export function Index(this: RenderData) { | |
// The actual layout has the proper "this", bound by Eleventy. | |
// But Eleventy doesn't manage the calling of the "shortcodes" aka | |
// components. Instead, Preact calls <Heading/> and binds its own "this". | |
const cssBundle = this.getBundle("css"); | |
return ( | |
<html> | |
<head> | |
<title>Hello TSX</title> | |
<style>{cssBundle}</style> | |
</head> | |
<body> | |
<h1>Hello ESM</h1> | |
<Heading /> | |
</body> | |
</html> | |
); | |
} | |
export const render = Index; | |
// Here's what the eleventyConfig setup looks like | |
eleventyConfig.addExtension(["11ty.jsx", "11ty.ts", "11ty.tsx"], { | |
key: "11ty.js", | |
compile: function () { | |
return async function (data) { | |
const content = await this.defaultRenderer(data); | |
const result = render(content, { | |
data, | |
shortcodes: eleventyConfig.javascriptFunctions, | |
}); | |
return `<!doctype html>\n${result}`; | |
}; | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment