Build a custom page in Drupal 8

In this example, the module is called Dribbit, so we have a dribbit directory in modules/custom where all code is placed.

The dribbit.info.yml file

name: 'Dribbit demo module'
description: 'Demo module used on dribbit.eu'
type: module
core: 8.x
package: 'Dribbit'

The dribbit.routing.yml file

dribbit.demopage:
  path: '/demopage'
  defaults:
    _controller: '\Drupal\dribbit\Controller\DemoPage::page'
    _title: 'Test page'
  requirements:
    _permission: 'access dribbit demopage'

The dribbit.permissions.yml file

access dribbit demopage:
  title: 'Aacess dribbit demopage'
  description: 'Custom permission to the Dribbit demo page.'
  restrict access: false

The dribbit.links.menu.yml file

dribbit.demopage:
  title: 'Test page'
  description: 'Test page'
  route_name: dribbit.demopage
  parent: main
  menu_name: main
  weight: 5

The routing Controller

The controller must return  response object or a render array.

<?php

/**
 * Created by PhpStorm.
 * User: Dribbit
 * Date: 16/06/18
 * Time: 06:51
 */

namespace Drupal\dribbit\Controller;

use Drupal\Core\Controller\ControllerBase;

class DemoPage extends ControllerBase {

  public function page() {
    return [
      '#markup' => 'Hello world',
    ];
  }

}