Customer Account Screen Hooks
The twenty-nine placement points of the dashboard, the account pages and invoices.
Overview
The placement points on the screens a signed-in customer sees live here: the dashboard, the account pages, the balance, subscriptions, the partner programme and invoices.
Two points fall outside that pattern: the invoice detail and the licence transfer result can open for somebody not signed in. Your output there must not depend on a session.
Reference
The top of the dashboard
Appears at the very top of the customer dashboard.
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.dashboard.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});After the dashboard panels
Appears after the panels on the dashboard.
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.dashboard.panels.after', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the dashboard
Appears at the very bottom of the dashboard.
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.dashboard.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});After the account tabs
Appears after the tab bar on the account 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.account.tabs.after', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});After the account cards
Appears after the account summary cards.
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.account.cards.after', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the profile form
Appears below the profile form. If you add a field, you must wire up its saving too.
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.account.profile.form.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});After the security section
Appears after the account security section.
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.account.security.after', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});After the settings
Appears after the account settings.
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.account.settings.after', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});After the sub-account list
Appears after the sub-user list.
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.sub_accounts.list.after', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});After the API keys
Appears after the API key list.
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.api_credentials.after', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the balance overview
Appears below the balance overview.
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.balance_overview.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The top of the balance history
Appears above the balance movement list.
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.balance_history.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the top-up form
Appears below the wallet top-up form.
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.add_funds.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The top of the subscriptions list
Appears above the list of payment agreements.
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.subscriptions.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The top of the partner dashboard
Appears at the top of the partner programme dashboard.
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.affiliate_dashboard.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});After the partner statistics
Appears after the partner statistics.
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.affiliate_stats.after', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The top of the reseller dashboard
Appears at the top of the reseller dashboard.
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.reseller_dashboard.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The certificate action area
Appears in the action area of the certificate dashboard.
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.ssl_dashboard.actions', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The top of the message panel
Appears at the top of the bulk message panel.
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.sms_panel.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The top of the message form
Appears above the message sending form. It suits a reminder that the charge is counted per part.
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.sms_send.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the message form
Appears below the message sending form.
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.sms_send.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The top of the invoice page
Appears at the very top of the invoice detail. It runs on an invoice opened through a share link too, where the visitor may not be signed in.
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.invoice_detail.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});After the invoice lines
Appears after the invoice lines.
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.invoice_detail.items_after', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});After the transaction list
Appears after the payment movements.
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.invoice_detail.transactions.after', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the invoice page
Appears at the very bottom of the invoice detail.
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.invoice_detail.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The top of the invoice list
Appears above the invoice list.
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.invoice_list.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The invoice list toolbar
Appears in the toolbar of the invoice list.
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.invoice_list.toolbar', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The top of the bulk payment page
Appears above the screen for paying several invoices together.
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.bulk_pay.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Above the transfer result page
Appears above the licence transfer result page. That page opens through a link in an email, so the visitor may not be signed in.
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.license_transfer_result.before', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Pitfalls
The invoice detail also opens through a share link, where the visitor has no session. Output depending on one comes out empty there, and showing customer details opens them to somebody you cannot identify.
A field you put on the account form is only visible. For the value to be kept you must also hook into the profile update flow; otherwise the customer fills it in, saves, and it disappears.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.