Kitten

Learn about the special HTML, HEAD, START_OF_BODY, BEFORE_LIBRARIES, AFTER_LIBRARIES, and END_OF_BODY slots that you can use to inject content into different parts of your page.

Topics covered

In addition to the slots you can define and use while authoring Kitten apps, there are a handful of special preset slots you can use to send content into places you wouldn’t otherwise be able to reach from your pages as they lie outside where your page is rendered in Kitten’s internal base layout component.

🐈 The internal base layout component is fully customisable.

The list of special page slots supported by kitten are HTML, HEAD, START_OF_BODY, BEFORE_LIBRARIES, AFTER_LIBRARIES, and END_OF_BODY.

💡 The HTML slot is unique in that you are expected to provide just the opening <html> tag, not the full document. It’s there so you can specify a different language (e.g., <html lang=uk'> for Ukrainian). Do not return anything else in the content for this slot or the sky will fall on your head. 🙀

Here’s an example, showing you most of the special page slots in use:

index.page.js

export default () => kitten.html`
  <page htmx alpinejs>

  <content for='HEAD'>
    <title>Special page slots</title>
    <link rel='icon' href='/favicon.ico'>
  </content>

  <h1>Special page slots</h1>

  <h2>This is just regular content on the page.</h2>

  <content for='START_OF_BODY'>
    <p>This is the <strong>start of the body</strong>.</p>
  </content>

  <content for='BEFORE_LIBRARIES'>
    <p>This is right <strong>before Kitten libraries</strong> (i.e., htmx and Alpine.js) are declared.</p>
  </content>

  <content for='AFTER_LIBRARIES'>
    <p>This is right <strong>after Kitten libraries</strong> are declared. It’s a good place to put scripts if you want to make sure the Kitten libraries are loaded and can be used.</p>
  </content>

  <content for='END_OF_BODY'>
    <p>This is the <strong>end of the body.</strong></p>
  </content>

  <style>
    body { font-family: system-ui, sans-serif; }
    p { padding: 1em; border: 0.25em solid deeppink; border-radius: 0.5em; }
  </style>
`

Notice how you can use the HEAD slot to set the title and specify an icon. Kitten has intelligent defaults for these that it uses if you forget (it tries to get the title from your page if you have a h1 tag and it sets the favicon to an empty one so you don‘t get load errors in your developer console, etc.)

🐈 Just like regular slots, you can specify more than one of the special page slots and any content you send there will stack.

You can also specify certain <head> properties in the <page> tag.

These are the title, charset, viewport, and icon properties. For anything else you want to add to the head of your web page, please use the special HEAD page slot.

💡 When a HEAD slot exists, it has priority over properties defined in <page> tags.

For example, you could also have written the above example as follows:

export default () => kitten.html`
  <page htmx alpinejs title='Special page slots' icon='/favicon.ico'>

  <content for='HEAD'>
    <title>Special page slots</title>
    <link rel='icon' href='/favicon.ico'>
  </content>

  <h1>Special page slots</h1>
  …
`

💡 In addition to regular (JavaScript) components and fragments, you can also have HTML, CSS, and Markdown fragments.

These are plain old HTML, CSS, and Markdown files that you can nevertheless import as if they were JavaScript functions. (Kitten uses the magic of ES Module Loaders to convert them to JavaScript modules.

You place HTML fragments into files that have a .fragment.html extension, CSS fragments into files that have a .fragment.css extension, and Markdown files into – you guessed it – files that have a .fragment.md extension.

HTML, CSS, and Markdown fragments support slots just like JavaScript fragments do (including named slots) but they do not support props (you can use named slots as a poor man’s props).

While they are not as flexible as JavaScript fragments, you might find them useful as your editor might give you better language intelligence than in HTML and CSS tagged template strings, to save on one level of indentation, or for organisational preferences.

Like JavaScript fragments, HTML, CSS, and Markdown fragments are ignored by the router.

For an example of their use, see the examples/html-and-css-fragments and examples/fragment-loaders in the Kitten source code.

Well, we’ve covered everything about components and fragments including all the different types of slots and layout components. So let’s learn about the unique way that Kitten – as a Small Web server – handles your cryptographic identity and authentication next.

Next tutorial: Authentication