Module Development

Routes for Drupal 8, 9, and 10

When a user visits a particular URL on a Drupal site, the path they are visiting is a route. Drupal's routing system helps figure out which controller is responsible for responding to the route being requested. Drupal matches the incoming request's path to a controller by looking through the routes that have been registered in active modules.

Example tasks

  • Create your own routes in custom modules
  • Understand how Drupal's routing system maps paths to controllers


At this point in the development cycle of Drupal the routing system is relatively stable. This is mainly because Drupal's routing system leverages the Symfony routing component.

Drupalize.Me resources

More information

Let's create our first page in our Symfony 4 app and learn about routes and controllers in the process.

More information

In this tutorial, we'll create a new module and create a route and controller for it. Remember hook_menu? Well, hook_menu is out and routes and controllers are in! If the YAML files in this lesson piqued your interest, check out our introduction to YAML tutorial to learn more.

Note: See Create an Info File for a Module for up-to-date instructions on info file requirements, which have changed since this video was recorded.

Create an Info File for a Module
An Introduction to YAML — Drupalize.Me
PHP Namespaces in 120 seconds
Clear Drupal's Cache

More information

In this tutorial, we'll continue to look under the hood of Drupal 8, this time using a tool bundled with Devel called Webprofiler. You'll learn how to use the web debug toolbar and the profiler. You'll also learn how to reverse engineer a page to find out the names of the controllers responsible for output on that page.

Note: Webprofiler is now a separate project from Devel but still has it as a dependency.

Note: In order to get the Webprofiler timeline view working you need to add some configuration to your settings.php file. See the file included with the Webprofiler module for more information on how to do this.

Webprofiler project on

More information

In this tutorial, you will learn how to return a response through a controller using route wildcards. We'll walk through how the wildcard in the route was created and then how this wildcard gets passed as a parameter to the controller function, enabling you to display a value to the page based on the value in a particular URL path segment using Symfony's Response object.

We're assuming you have the Drupal Console up and running (which we set up in the previous tutorial). The drupal command calls Drupal Console.

Curious about the inner workings of the HTTP response? Dive into Symfony and HTTP Fundamentals, which takes you from HTTP fundamentals to how PHP handles HTTP requests and responses, and integrates what Symfony's tools bring to this flow from request to response.

Symfony and HTTP Fundamentals — Symfony Documentation
Http Foundation Response Object — Symfony Documentation

Drupal 8, 9, and 10
More information

Before you can create a path or link to another page on your site, you'll need to know the route (unless there is already a variable available for the URL you need). Finding a route can be a tricky task unless you have the right tools. In this tutorial, we'll show how tools like Webprofiler, Drush, and Grep can be used to get route information for a page, so that you can use functions that need a route as a function parameter.

In this tutorial we'll:

  • Learn how to determine the route or path of an internal page.
Drupal 8, 9, and 10
More information

In this tutorial we will learn how to add menu links using a custom Drupal module. We will also look at the options available for configuring our new menu link. Lastly, we'll learn about using hook_menu_links_discovered_alter() that can be used to add new menu links, or alter the behavior of existing ones.

More information

Each form is defined by a controller, a class that implements the \Drupal\Core\Form\FormInterface. Form controllers declare the unique ID of the form, the $form array that describes the content of the form, how to validate the form, and what to do with the data collected.

In this tutorial we'll:

  • Define a new form controller class
  • Implement the required methods to describe a form
  • Add a route that can be used to access our form

By the end of this tutorial you should be able to define a form that adheres to the FormInterface requirements and know where to find more information about how to further customize your form controller.

This tutorial walks through the process of creating a custom content entity. Since there are several url paths that will display various types of information about our custom entity there are multiple examples of registering routes in this tutorial as well.

Drupal 8, 9, and 10
More information

The Drupal Entity API makes it easy to define new custom content entity types. And in most cases whenever you want to store custom content in Drupal you should use the Entity API instead of making CRUD queries directly to the database. This ensures your code is more consistent, and allows you to take advantage of all the features of the Entity API like access control, Views module integration, and automatic JSON:API support. As well as making it easier for others to extend your custom content by ensuring all the proper hooks and lifecycle events get invoked when new content items get created, updated, and deleted.

In this tutorial we'll:

  • Walk through the process of creating a custom content entity

By the end of this lesson you'll be able to create your own custom content entity contained in a module.

Related topics

Drupal 8, 9, and 10
More information

Controllers are the portion of a Drupal module that handle responding to an incoming request with the appropriate response data.


Drupal 7, 8, 9, and 10
More information

A site’s main navigation elements, whether they be in the header, footer, or sidebar, are composed of links built using Drupal's menu system. Drupal allows site administrators to build menus while also allowing module developers to add and alter menus in code.


Not sure where to start? Our guides provide useful learning tracks for all skill levels.

Navigate guides

External resources

  • Routing system overview (
    • The main entry point for Drupal's official documentation about the routing system.
  • Symfony's routing component (
    • The official documentation for the Symfony routing component that Drupal's routing system is based on.
  • Structure of routes (
    • This page in particular covers the variety of configuration options that make up routing configuration files.
  • Examples projects page_example module (
    • The Examples for Developers project contains many sub-modules that demonstrate various Drupal sub-systems through well-documented code. To learn more about how routing and controllers work, take a look at the Examples for Developers project's page_example module.