Create your first Symfony page

Creating a new page — either an HTML page or a JSON endpoint — is done in two steps:

  1. Create a route: The route is a URL that points to your page (such as /about) and maps to a controller.
  2. Create a Controller: A controller is a feature that you write to structure your page. Get the incoming request information and use it to create a Symfony Response object, which can contain HTML content, a JSON string or even binary files such as images or PDFs.

Create a page: route and controller

Before you begin, make sure you have read the installing and configuring Symfony section and have access to your Symfony application in a browser.

Suppose you want to create a new /lucky/number page that generates a random lucky number and outputs it. To do this, first create a controller class and controller methods:

// src/Controller/LuckyController.php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;

class LuckyController
    public function number()
        $number = random_int(0, 100);

        return new Response(
            '<html><body>Lucky number: '.$number.'</body></html>'

Now you need to associate this controller function with a public URL(for example: /lucky/number) so that the number() method can be executed when the user visits the link. Define this association by creating a route in the config/routes.yaml file:

# config/routes.yaml

# the "app_lucky_number" route name is not important yet
    path: /lucky/number
    controller: App\Controller\LuckyController::number

So, if you’re using the Symfony Web service, try this:


If you see the lucky number printed to the browser, congratulations! But before you start playing the lottery, understand how it works. Remember the two steps of creating a page?

  1. Create a route: atconfig/routes.yamlIn the file, the route defines the mapping of the URL to the page and the controller to invoke. In this section you will learn more about routing, including how to create variable URLs.
  2. Create a Controller: This is the ability to build and ultimately return a Response object. In this section you will learn more about controllers, including how to return a JSON Response.

To create controllers faster, we can ask Symfony to generate:

$ php bin/console make:controller

The Annotation of routing

In addition to YAML, Symfony allows the use of annotations to define routes. To do this, install the Annotation package:

$ composer require annotations

You can add routes directly above the controller:


// src/Controller/LuckyController.php

// ...
+ use Symfony\Component\Routing\Annotation\Route;

class LuckyController
+     /**
+      * @Route("/lucky/number")
+      */
    public function number()
        // this looks exactly the same

In this way, the page – http://localhost/lucky/number will work as before! Annotations is a recommended way to configure routing.

Automatically install “Recipes” with Symfony Flex

You may not have noticed it, but two special things happened when you ran Composer Require Annotations, thanks to a powerful Componser plug-in called Flex.

First, annotations aren’t really a package name: It’s an alias that Flex resoles to sensio/framework-extra-bundle.

Second, after the package is downloaded, Flex executes a “recipe,” which is a set of automatic instructions that tell Symfony how to inherit from the external package. Flex “recipes” work with many packages and can do many things, such as adding configuration files, creating directories, updating.gitignore, and adding new configurations to.env files. Flex automatically installs packages so you can focus on coding.

You can learn more about Flex by reading “Using Symfony Flex to Manage Symfony Applications”. But this is not necessary: Flex runs automatically in the background when you add packages.

Bin/console command

Your project has been integrated with a powerful debugging tool: the bin/console command. Try running it:

$ php bin/console

You should see a list of commands that will give you debugging information, help you generate code, generate database migration, etc. As you install more packages, you will see more commands.

To get a list of all routes on your system, use the debug:router command:

php bin/console debug:router

You can see your app_lucky_number route at the top:

Name Method Scheme Host Path
app_lucky_apinumber ANY ANY ANY /lucky/number

You’ll also see the debug route after app_lucky_number – more on that in the next section.

Web Debugging Toolbar: Debugging Dream

The Web Debug Toolbar is one of Symfony’s killer tools: a lot of debugging information is output at the bottom of the page during development for easy debugging. Install symfony/profiler-pack right out of the box.

Once installed, a black toolbar appears at the bottom of the page. You’ll learn more about all the information it contains, and feel free to try it out: you can get routing, performance, logging, and more by hovering over or clicking on different ICONS in the toolbar.

Apply colours to a drawing template

If you want to return HTML from the controller, you might need to render a template. Fortunately, Symfony comes with Twig: a simple, powerful, and very fun templatinglanguage.

Ensure that LuckyController inherits the base AbstractController class of Symfony:

// src/Controller/LuckyController.php

// ...
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

- class LuckyController
+ class LuckyController extends AbstractController
    // ...

Now, use the simple render() function to render the template. Pass a numeric variable so that you can use it in Twig:

// src/Controller/LuckyController.php

// ...
class LuckyController extends AbstractController
     * @Route("/lucky/number")
    public function number()
        $number = random_int(0, 100);

        return $this->render('lucky/number.html.twig', [
            'number' => $number,

The templates files reside in the templates/ directory, which is automatically created when you install Twig. Create a new directory templates/lucky and in that directory create the template file Number.html. twig and say: “templates”.

{# templates/lucky/number.html.twig #}

<h1>Your lucky number is {{ number }}</h1>

The {{number}} syntax is used in Twig to print variables. Refresh your browser to get the new lucky number.


Now you might be wondering where the Web Debug tool went: that’s because the tag is not in the current template. You can add the body element yourself, or extend the base.html.twig to include all the default HTML elements.

In the Creating and Using Templates section, you’ll learn all about Twig: how to render, render other templates, and take advantage of its powerful layout inheritance system.

View the project structure

The good news! You are already working in the most important directory in your project:


Configure routes, services, and packages


All the PHP code is here.


All Twig template files are here.

Most of the time, you’ll be working in SRC /, templates/, or config/. As you read on, you’ll learn what to do in each category.

What about the other directories in the project?


The famous' bin/console 'file exists here (along with other less important executables).


Files created automatically by the project are stored here, such as cache files (' var/cache/ ') and (' var/log ').


Third-party (i.e. "vendor") libraries are here! These are downloaded through the Composer package manager.


This is the document root of your project: you can place any publicly accessible files in this directory.

When you install a new package, a new directory will be created automatically when needed.