diff --git a/guide/under-the-hood.md b/guide/under-the-hood.md
index 36548f4..ba5744d 100644
--- a/guide/under-the-hood.md
+++ b/guide/under-the-hood.md
@@ -127,3 +127,215 @@ Now when we render our `HelloWorld` component, we should see the following outpu
```html
` onto the buffer and continue as before.
+
+```ruby{2-8}
+def div(content = nil, **attributes)
+ @buffer << "
"
+
+ if content
+ @buffer << content
+ elsif block_given?
+ yield
+ end
+
+ @buffer << "
"
+end
+```
+
+Let’s go back to our `HelloWorld` component and add a class attribute to each of the divs.
+
+```ruby
+class HelloWorld < Component
+ def view_template
+ div(class: "outer") {
+ div("Hello, World!", class: "inner")
+ }
+ end
+end
+```
+
+Now when we render our `HelloWorld` component, we should see the following output:
+
+```html
+
+```
+
+## Nesting components
+
+For the final step, let’s add the ability to nest components inside one another.
+
+To do this we’ll need the ability to pass a buffer to a component when we come to rendering it. Let’s remove the original `initialize` method and update the `call` method to accept a buffer argument instead.
+
+We’ll also accept a block (`&`) and pass it to the `view_template` method.
+
+```ruby
+def call(buffer = [], &)
+ @buffer = buffer
+ view_template(&)
+ @buffer.join
+end
+```
+
+The buffer still defaults to an empty array, but now we can pass in a buffer from the outside. The block allows us to yield content in our template.
+
+Let’s define a `render` method that takes a component and renders, passing the buffer and the block.
+
+```ruby
+def render(component, &)
+ component.call(@buffer, &)
+end
+```
+
+The whole `Component` class should now look like this:
+
+```ruby
+class Component
+ def call(buffer = [], &)
+ @buffer = buffer
+ view_template(&)
+ @buffer.join
+ end
+
+ def div(content = nil, **attributes)
+ @buffer << "
"
+
+ if content
+ @buffer << content
+ elsif block_given?
+ yield
+ end
+
+ @buffer << "
"
+ end
+
+ def render(component, &)
+ component.call(@buffer, &)
+ end
+end
+```
+
+Now let’s create a new component called `Card`:
+
+```ruby
+class Card < Component
+ def view_template(&)
+ div(class: "card", &)
+ end
+end
+```
+
+Back in our `HelloWorld` component, let’s update it to render our `Card` component:
+
+```ruby
+class HelloWorld < Component
+ def view_template
+ div(class: "outer") {
+ render Card.new do
+ div("Hello, World!", class: "inner")
+ end
+ }
+ end
+end
+```
+
+The output should now be something like this (without newlines and indentation):
+
+```html
+
+```
+
+## Plain text
+
+In about 30 lines of code, we’ve build a simple component abstraction for rendering HTML. We can render nested divs with content and attributes and we can nest components inside one another.
+
+However, what we can’t do is render text without wrapping it in a div. Let’s fix that with a new method called `plain` that simply pushes content onto the buffer.
+
+```ruby
+def plain(content)
+ @buffer << content
+end
+```
+
+Now we can update our `HelloWorld` component to render the text directly inside the `Card` component:
+
+```ruby
+class HelloWorld < Component
+ def view_template
+ div(class: "outer") {
+ render Card.new do
+ plain "Hello, World!"
+ end
+ }
+ end
+end
+```
+
+## Supporting advanced DSLs
+
+What if we want to our Card component to expose an interface for interacting with it. For example, we might want to set the title.
+
+Let’s start by updating the Card component as if this worked and then we’ll get it working.
+
+```ruby
+class Card < Component
+ def view_template(&)
+ div(class: "card", &)
+ end
+
+ def title(content)
+ div(content, class: "card-title")
+ end
+end
+```
+
+This `title` method perfectly encapsulates the card title. But how can we call it at just the right moment so that it pushes to the buffer in the right place?
+
+The trick here is to yield the component to the block that’s passed to `view_template` from the `render` method. This will allow us to pick up the card component when passing in the block.
+
+```ruby
+class HelloWorld < Component
+ def view_template
+ div(class: "outer") {
+ render Card.new do |card|
+ card.title "Hello, World!"
+ end
+ }
+ end
+end
+```
+
+To get this to work, we’ll need to find the point where we yield and make it `yielf(self)`. We could do this in the `div` method, but there’s a better way.
+
+When the block comes into `call`, we can wrap it in a new block that yields `self`. This way, it will always yield the component instance even if we forget to.
+
+```ruby
+def call(buffer = [])
+ @buffer = buffer
+ view_template { yield(self) if block_given? }
+ @buffer.join
+end
+```
+
+This is a little mind-bending. We’re now always passing a block to `view_template`, that yields self to the block that was passed to `call` if a block was passed.