TSX components and subcomponents don't have access to shortcodes. The
this.context.shortcodes.css()
function runs, but doesn't put its content into the bundle.
The 11ty docs cover the setup of TypeScript and TSX.
That page shows the use of renderToStaticMarkup
from react-dom/server
. This repo uses
Preact and preact-render-to-string.
Its render
function takes
a second argument
as a "context" which is an object that is available as this.context
on all components.
I'd like shortcodes such as the Nunjucks {% css %}em { font-style: italic; }{% endcss %}
to be available in JSX/TSX. It doesn't have to be in the markup. It can be done in a JavaScript call in the component.
I'd like this to be available in both the layout component and any subcomponents. I make this distinction because 11ty manages the first, but not the second.
When a layout component is called, it's just a normal JavaScript template. 11ty handles it by doing a bind()
and
making the this
into an object managed by 11ty. The this
then has access to all the goodness a template might want.
Subcomponents are different though. They are instantiated by Preact. They get a this
that is manage by Preact. As a
note, this also means that layouts don't get this.context
as Preact didn't create that instance.
The eleventy.config.js
adds the bundle plugin and a bundle for css
. In the compile
function, it shoves the
shortcodes into the Preact context:
const content = await this.defaultRenderer(data);
const result = render(content, {
data,
shortcodes: eleventyConfig.javascriptFunctions,
});
This allows subcomponents to grab the css()
callable as this.context.shortcodes.css
. You can see this in the
_includes/Heading.tsx
subcomponent.
_includes/BaseLayout.11ty.tsx
shows the problem. When this line is run:
const cssBundle = this.getBundle("css");
...it is executed before the subcomponent is run. Most likely, there's an order-of-execution problem. The JSX
immediately invokes this.getBundle("css")
.