Controllers are the Erlang modules which decide what happens when a browser requests a page. Zotonic looks at the dispatch rules that match the requested URL, and if a dispatch rule matches, the controller that is named in the dispatch rule is used to handle the request.

Anatomy of a controller

Say we have the following dispatch rule, handling https://localhost/example:

{example_url, [ "example" ], controller_example, []},

When hitting /example, the controller_example controller will be initialized and callback functions on the controller will be called, according to the HTTP protocol flow.

Controllers are pretty self-documenting, thanks to the names of the cowmachine callback functions. For instance, when you define a function resource_exists/1, it will be called to decide if the page should return a 404.

The simplest controller to serve HTML:


-export([ process/4 ]).

process(_Method, _AcceptedCT, _ProvidedCT, Context) ->
    {<<"<h1>Hello</h1>">>, Context}.

Rendering templates

To return the rendered output of a template file in the module’s priv/templates directory, use z_template:render_to_iolist/3:


-export([ process/4 ])

process(_Method, _AcceptedCT, _ProvidedCT, Context) ->
    % foo and bam will be available as template variables in mytemplate.tpl.
    Vars = [
       {foo, <<"bar">>},
       {bam, 1234}
    z_template:render_to_iolist("mytemplate.tpl", Vars, Context).

If you need more examples, mod_base contains many controllers, implementing basic HTTP interaction but also redirects, websockets, et cetera. The Controllers page lists all available controllers in the Zotonic core.

The Cowmachine documentation is helpful for understanding controllers.

Differences between Cowmachine and Basho’s Webmachine

Zotonic’s fork of Webmachine has been named cowmachine and lives in its separate repository at

The main differences with Basho’s Webmachine are:

  • Uses Cowboy instead of MochiWeb
  • All callbacks have a single handler
  • Pluggable dispatch handler
  • Support for the HTTP Upgrade: header
  • Optional caching of controller callbacks results
  • Dispatch handler can redirect requests
  • Use of process dictionary has been removed
  • webmachine_request is now a normal (not parametrized) module
  • Extra logging
  • ping and init callbacks are removed

Together, this is a significant simplification and speed boost.

The Status site Developer Guide Dispatch rules

Referred by


Action An action is functionality that can be attached to a HTML element or event. Actions are wired to an element or…


Modules are the building blocks of Zotonic. They add functionality to your Zotonic website such as:


Templates are text files marked up using the Zotonic template language. Zotonic interprets that mark-up to dynamically…


This is the full list of controllers that are available in Zotonic. For more general information about controllers, see…

Dispatch rules

Dispatch rules route incoming requests to controllers.

Create a custom controller

Zotonic comes with a large collection controllers that cover many use cases, so you’ll probably have to resort to…