nunjucksjamstackeleventy

Page <style> in Header for 11ty


I am new to 11ty and Nunjucks, but I cannot find this answer anywhere. I would like to add a page-specific style block in the template head tag from a page. I come from a Vue/Nuxt background, and I really like how you can scope a CSS block to the component/page, and they automatically put it in the head tag for you.

Here is my overall layout:

index.njk

---
layout: default.njk
title: Home
---

<img src="http://lorempixel.com/1200/300/sports/5" style="width: 100%;" />
<div class="container">
  <h1>11ty Test</h1>
</div>

{% block customstyles %}
  <style>
    .container{
      background: red;
    }
  </style>
{% endblock %}

_includes/default.njk

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ title }}
      | 11ty Sandbox</title>
    {% block customstyles %}
      This is the default content
    {% endblock %}
  </head>
  <body>
    {{ content | safe }}
  </body>
</html>

It works to a point, but the style tag is in the body, not the head, and the block doesn't work as I understand it. What am I missing?


Solution

  • The problem is that you cannot use {% block %} in a content file ... they can only be used in a file located in _includes. Here is a version of your exmaple that does work ...

    _includes/default.njk

    This is your base layout from which all other layouts "extend"

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>{{ title }}
          | 11ty Sandbox</title>
        {% block customstyles %}
          This is the default content
        {% endblock %}
      </head>
      <body>
        {% block body %}
        {{ content | safe }}
        {% endblock %}
      </body>
    </html>
    

    _includes/simple.njk

    This is the layout just for "simple" pages. Notice that it uses {% extends "default.njk" %} and it uses the {% block customstyles %} to provide a custom style.

    {% extends "default.njk" %}
    {% block customstyles %}
      <style>
        .container{
          background: red;
        }
      </style>
    {% endblock %}
    {% block body %}
    <img src="{{ image }}" style="width: 100%;" />
    <div class="container">
      <h1>{{ title }}</h1>
      {{ content | safe }}
    </div>
    {% endblock %}
    
    

    index.njk

    This page is just the content, image and title and it is rendered using the "simple" layout.

    ---
    layout: simple.njk
    title: Home
    image: http://lorempixel.com/1200/300/sports/5
    ---
     
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    
    Sed finibus, velit a tristique hendrerit, nisl nisi aliquet diam, a vulputate tortor quam et odio. 
    
    Vivamus vitae magna a eros suscipit luctus a quis lorem.