This is the cleanest and most reliable solution I've found so far. It uses localStorage and view models like the core toolbar itself. These are the important parts of my module:
toolbar_always_vertical.info.yml
name: 'Toolbar always vertical on the left'
type: module
description: 'Shows the toolbar by default in vertical mode, on the left side and hide it on frontend pages.'
core: 8.x
dependencies:
- toolbar
toolbar_always_vertical.libaries.yml
toolbar:
version: 0.0.1
js:
js/toolbar.js: {}
dependencies:
- toolbar/toolbar
toolbar_always_vertical.module
function toolbar_always_vertical_preprocess_html(&$variables) {
$variables['#attached']['library'][] = 'toolbar_always_vertical/toolbar';
}
js/toolbar.js
(function ($, Drupal, drupalSettings) {
Drupal.behaviors.toolbarAlwaysVerticalSetToolbarDefaults = {
attach: function (context, settings) {
if (Drupal.toolbar.views.toolbarVisualView) {
// this forces the vertical orientation
localStorage.setItem('Drupal.toolbar.trayVerticalLocked', 'true');
Drupal.toolbar.views.toolbarVisualView.model.set({locked: true, orientation: 'vertical'}, {validate: true, override: true});
if (drupalSettings.path.currentPathIsAdmin && Drupal.toolbar.views.toolbarVisualView.model.attributes.isFixed) {
// show administration toolbar when in admin and not collapsed
Drupal.toolbar.views.toolbarVisualView.model.set({activeTab: $('#toolbar-item-administration')});
}
else {
// hide toolbar when on frontend page
Drupal.toolbar.views.toolbarVisualView.model.set({activeTab: null});
}
}
}
};
})(jQuery, Drupal, drupalSettings);
There is a critical point all other answers missed: it has to be done in a module and not in a theme, because only modules can add dependencies to other modules and guarantee that the code is exectued after the core toolbar.