Customer Site Shell Hooks
The sixteen placement points shared by every page: the head, the body, menus and the footer.
Overview
The placement points present on every page of the site live here: the head section, the body, the menus, the footer and the system pages.
What they share is scale: what you place here runs on the home page, at the payment step and on an error page alike. Weigh the cost at that scale.
Reference
Adding a style to the site
Appears in the head section of the site, on every page. Link a stylesheet of your own here.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.head.css', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Adding a script to the site
The place to add a script on every page. It is the first thing a visitor meets: a heavy file delays the page opening.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.head.js', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The start of the body
Appears at the very start of the page body. It suits an announcement banner across the site.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.body.begin', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The end of the body
Appears at the very end of the page body. The right place for modals and tracking scripts.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.body.end', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The end of the top bar
Appears at the end of the top bar.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.topbar.end', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The header action area
Appears in the action area of the site header.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.header.actions', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The main menu items
Appears among the items of the main menu. Use the same item markup so the menu structure holds.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.nav.items', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The sub-menu items
Appears among the items of the sub-menu.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.subnav.items', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The user menu items
Appears in the menu of a signed-in user.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.user_menu.items', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The drawer items
Appears among the items of the mobile drawer. It is separate from the main menu: add to both if you want it in both places.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.drawer.items', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Above the footer
Appears immediately above the footer.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.footer.before', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The footer columns
Appears among the footer columns.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.footer.columns', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the footer
Appears at the very bottom of the footer.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.footer.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Above the call-to-action band
Appears above the call-to-action band at the foot of the page.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.cta_band.before', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The maintenance page body
Appears in the body of the maintenance page. It runs while the site is closed: a listener reaching the database or an outside service here can take down the page at an already bad moment.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.maintenance.body', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The system page head
Appears in the head of the error and blocked pages. Those pages are shown even when the core has failed: give simple output with no dependencies.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:client.system_page.head', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Pitfalls
The head and body points run on every page of the site, the basket and the payment step included. A slow script there delays not one page but the purchase path itself.
The maintenance and system page points run at the moment the site is already in trouble. A listener reaching for the database or an outside service there takes down the last page the user would have seen. Give simple output with no dependencies.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.