--- title: Hooks permalink: /docs/plugins/hooks/ --- Using hooks, your plugin can exercise fine-grained control over various aspects of the build process. If your plugin defines any hooks, Jekyll will call them at pre-defined points. Hooks are registered to an owner and an event name. To register one, you call `Jekyll::Hooks.register`, and pass the hook owner, event name, and code to call whenever the hook is triggered. For example, if you want to execute some custom functionality every time Jekyll renders a page, you could register a hook like this: ```ruby Jekyll::Hooks.register :pages, :post_render do |page| # code to call after Jekyll renders a page end ``` *Note: The `:post_convert` events mentioned hereafter is a feature introduced in v4.2.0.* Out of the box, Jekyll has pre-defined hook points for owners `:site`, `:pages`, `:documents` and `:clean`. Additionally, the hook points defined for `:documents` can be utilized for individual collections only by invoking the collection type instead. i.e. `:posts` for documents in collection `_posts` and `:movies` for documents in collection `_movies`. In all cases, Jekyll calls your hooks with the owner object as the first callback parameter. Every registered hook owner supports the following events — `:post_init`, `:pre_render`, `:post_convert`, `:post_render`, `:post_write` — however, the `:site` owner is set up to *respond* to *special event names*. Refer to the subsequent section for details. All `:pre_render` hooks and the `:site, :post_render` hook will also provide a `payload` hash as a second parameter. While in the case of `:pre_render` events, the payload gives you full control over the variables that are available during rendering, with the `:site, :post_render` event, the payload contains final values after rendering all the site (useful for sitemaps, feeds, etc). ## Built-in Hook Owners and Events The complete list of available hooks:
Owner Event Triggered at

:site

Encompasses the entire site

:after_init

Just after the site initializes. Good for modifying the configuration of the site. Triggered once per build / serve session

:after_reset

Just after the site resets during regeneration

:post_read

After all source files have been read and loaded from disk

:pre_render

Just before rendering the whole site

:post_render

After rendering the whole site, but before writing any files

:post_write

After writing all of the rendered files to disk

:pages

Allows fine-grained control over all pages in the site

:post_init

Whenever a page is initialized

:pre_render

Just before rendering a page

:post_convert

After converting the page content, but before rendering the page layout

:post_render

After rendering a page, but before writing it to disk

:post_write

After writing a page to disk

:documents

Allows fine-grained control over all documents in the site including posts and documents in user-defined collections

:post_init

Whenever any document is initialized

:pre_render

Just before rendering a document

:post_convert

After converting the document content, but before rendering the document layout

:post_render

After rendering a document, but before writing it to disk

:post_write

After writing a document to disk

:posts

Allows fine-grained control over all posts in the site without affecting documents in user-defined collections

:post_init

Whenever a post is initialized

:pre_render

Just before rendering a post

:post_convert

After converting the post content, but before rendering the postlayout

:post_render

After rendering a post, but before writing it to disk

:post_write

After writing a post to disk

:clean

Fine-grained control on the list of obsolete files determined to be deleted during the site's cleanup phase.

:on_obsolete

During the cleanup of a site's destination before it is built

## Hooks for custom Jekyll objects You can also register and trigger hooks for Jekyll objects introduced by your plugin. All it takes is placing `trigger` calls under a suitable `owner` name, at positions desired within your custom class and registering the `owner` by your plugin. To illustrate, consider the following plugin that implements custom functionality for every custom `Excerpt` object initialized: ```ruby module Foobar class HookedExcerpt < Jekyll::Excerpt def initialize(doc) super trigger_hooks(:post_init) end def output @output ||= trigger_hooks(:post_render, renderer.run) end def renderer @renderer ||= Jekyll::Renderer.new( doc.site, self, site.site_payload ) end def trigger_hooks(hook_name, *args) Jekyll::Hooks.trigger :excerpts, hook_name, self, *args end end end Jekyll::Hooks.register :excerpts, :post_init do |excerpt| Jekyll.logger.debug "Initialized:", "Hooked Excerpt for #{excerpt.doc.inspect}" end Jekyll::Hooks.register :excerpts, :post_render do |excerpt, output| return output unless excerpt.doc.type == :posts Foobar.transform(output) end ```