Skip to content

Instantly share code, notes, and snippets.

@pauleveritt
Created June 19, 2024 20:29
Show Gist options
  • Save pauleveritt/8954fa66f43ef3fa604928a25eac2507 to your computer and use it in GitHub Desktop.
Save pauleveritt/8954fa66f43ef3fa604928a25eac2507 to your computer and use it in GitHub Desktop.
11ty TSX subcomponents and shortcakes
/*
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