How to output from custom module without rest of theme What the proper method of outputting a page from your module without any additional theming beyond your template, for example to make a page that is good for printing?

I've tried a few different methods based on Drupal 7 versions. The only one to work being to render the build array and the kill further PHP loading, however this doesn't feel right. In Drupal 7, I could set up a 'delivery callback' in the hook_menu() - but I can't seem to figure out how to replicate that behaviour now.

my_module.routing.yml:

my_module.user_timesheets:
  path: '/my_module/timesheets/{weekOf}/{uid}'
  defaults:
    _controller: '\Drupal\my_module\Controller\MyModuleAdminController::timesheets'
    _title: 'My Module Timesheets'
  requirements:
    _permission: 'admin'


my_module.module:

  $theme['timesheets'] = [
    'render element' =&gt; 'build',
    'template' =&gt; 'timesheets',
  ];


MyModuleAdminController.timesheets:

public function timesheets($weekOf, $uid = null) {
    $build['#theme'] = 'timesheets';

    ...code building values...

    $build['#staff'] = $staff;

    $build['#title'] = 'Timesheets - ' . $weekOf . ' to ' . $this-&gt;dateService-&gt;getWeekStartDate($weekOf);
    $build['#attached']['library'][] = 'my_module/timesheets';
    //print render($build);
    //die();
    return $build;
  }


my_module.libraries.yml:

timesheets:
  css:
    theme:
      lib/timesheets.css: {}


Edit:
   To over-ride something like page.html.twig in your module, you make a template called page--my_module--html.twig and then declare it in your modules my_module_theme() function.

/**
 * Implements hook_theme().
 */
function my_module_theme() {
  $theme['page__my_module__timesheets'] = [
    'template' =&gt; 'page--my_module--timesheets',
  ];

   return $theme;
}
The controller does not have to return a render array, it can also provide a symphony response, for example:

use Symfony\Component\HttpFoundation\Response;

$response = new Response();
$response-&gt;setContent('&lt;h1&gt;Hello world&lt;/h1&gt;');
//$response-&gt;headers-&gt;set('Content-Type', 'text/xml');
return $response;


This will bypass the Drupal rendering and theming.

Edit:

You can use two approaches to replace your Drupal 7 code:

1) Override page.html.twig and html.html.twig, remove anything out of this templates and put only that in what you want.

2) Render the HTML like you are doing it now in Drupal 7 and use a Symfony response.

Rendering in Drupal 8:

use Symfony\Component\HttpFoundation\Response;

$output = \Drupal::service('renderer')-&gt;renderRoot($build);

$response = new Response();
$response-&gt;setContent($output);

return $response;