Override page template and preserve administration navigation bar Short version; I am trying to override the default page.html.twig (in D8) for a controller from my module and the following examples I've found have not worked:


https://www.drupal.org/node/2499827
Override html.twig.html within custom module


My company is developing a custom module to embed a React app we originally built for another system inside the admin side of Drupal. As such, we would like to keep the admin navigation visible but the main body of the page should just be the react app. 

So far, I have successfully embedded the app as the content of a page, but still have the page's header, footer, breadcrumbs, etc. I'm not sure if I'm declaring my module's theme incorrectly, or if my naming is wrong for my template, or something else.



Thanks in advance!

Module name: my_module



my_module.info.yaml

name: Overriding page module 
description: "Module with a template that overrides the default page.html.twig" 
package: mystuff

type: module 
core: 8.x


my_module.module
    

function my_module_theme() {
    $theme['page__my_module'] = [
        'template' =&gt; 'page--my_module',
    ];

    return $theme;
}


my_module.routing.yml

my_module.content:
  path: '/hello'
  defaults:
    _controller: '\Drupal\my_module\Controller\HelloController::content'
    _title: 'Hello World'
  requirements:
    _permission: 'access content'


templates/page--my_module.html.twig

{#
  Taken from https://api.drupal.org/api/drupal/core%21themes%21seven%21templates%21page.html.twig/8.2.x
#}

  &lt;header class="content-header clearfix"&gt;
    &lt;div class="layout-container"&gt;
      {{ page.header }}
    &lt;/div&gt;
  &lt;/header&gt;

  &lt;div class="layout-container"&gt;
    {{ page.pre_content }}
    {{ page.breadcrumb }}
    &lt;main class="page-content clearfix" role="main"&gt;
      &lt;div class="visually-hidden"&gt;&lt;a id="main-content" tabindex="-1"&gt;&lt;/a&gt;&lt;/div&gt;
      {{ page.highlighted }}
      {% if page.help %}
        &lt;div class="help"&gt;
          {{ page.help }}
        &lt;/div&gt;
      {% endif %}
      &lt;h1 style="color:pink;"&gt;WHY DOESN'T THIS TEMPLATE GET USED!?&lt;/h1&gt;
      {{ page.content }}
    &lt;/main&gt;

  &lt;/div&gt;


src/Controller/HelloController.php

&lt;?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;

class HelloController extends ControllerBase {
    public function content() {
        return array(
            '#type' =&gt; 'markup',
            '#theme' =&gt; 'my_module',
            '#markup' =&gt; $this-&gt;t('Hello World!')
        );
    }
}


UPDATED

Thanks to @kiamlaluno, I found I could use the theme suggestions hook to tell drupal what theme to apply. I changed my_module.module to:

&lt;?php

function my_module_theme_suggestions_page(array $variables) {
  $path = explode('/', trim(\Drupal::service('path.current')-&gt;getPath(), '/'));
  if (isset($path[0]) &amp;&amp; $path[0] == 'hello') {
    return 'page--my-module';
  }
} 

function my_module_theme() {
    $theme['page--my-module'] = [
        'template' =&gt; 'page--my_module',
    ];

    return $theme;
}


and removed the #theme item from the controller's render array. It works now!
What the code is missing is the code that sets those variables the template file is using. Since you are using page--mymodule as template name, the module needs to implement template_preprocess_page__mymodule().
Alternatively, you can suggest a template file using hook_theme_suggestions_page().
function my_module_theme_suggestions_page(array $variables) {
  $path = explode('/', trim(\Drupal::service('path.current')-&gt;getPath(), '/'));
  if (isset($path[0]) &amp;&amp; $path[0] == 'hello') {
    return 'page--mymodule';
  }
} 

Implementing hook_theme_suggestions_page() like I show, page--mymodule.html.twig will get the variables set in template_preprocess_page(), which are the same variables passed to page.html.twig.