
Guided Tours in Joomla
Joomla can teach people how to use Joomla. Open a fresh Joomla 6 backend, and a small popover sometimes appears offering to walk you through a screen, one highlighted step at a time. That is a guided tour, and the same feature you see as a new user is something you can author yourself.
This article explains how Joomla's Guided Tours component (com_guidedtours) really works. It covers the basics for owners and editors who just want to follow a tour, the daily setup for administrators who want to build onboarding for their clients, and the technical details for developers who want to understand the database, the system plugin, and the Shepherd.js layer underneath.
Interactive, step-by-step help that lives inside Joomla itself, with no third-party extension needed.
The goal is simple: help you understand Guided Tours well enough to build your own tours with confidence and to troubleshoot them when they misbehave.
1. The Basics
1.1 What Are Guided Tours?
A guided tour is a sequence of small popovers that highlight parts of a Joomla screen and explain them in order. You have probably met them already: the "What's New" tour that greets you after an upgrade, or the tour that walks a first-time user through creating an article.
Joomla introduced Guided Tours as a core component in version 4.3 (April 2023). It has shipped and improved in every release since. A few things make it special:
- It is built into core. You do not install anything.
- A tour is data, not code. Each tour and each step is a database row you edit through the backend, no PHP required.
- It uses a well-known JavaScript library, Shepherd.js, to draw the popovers and dim the rest of the page.
- Tours are tied to a screen. A tour appears only on the page or component it belongs to.
1.2 A Tour and Its Steps
The model has just two levels:
| Object | Role |
|---|---|
| Tour | The container. It has a title, a description, the page it starts on, and which extensions it belongs to. |
| Step | One popover. It points at a part of the screen, shows a title and some text, and decides how the user moves on. |
A tour is an ordered list of steps. The first thing a user sees is an intro popover built from the tour title and description, then step 1, step 2, and so on until the final step shows a Complete button.
1.3 Where Do I Find It?
In the Joomla 6 backend, the relevant places are:
Users → Guided Tours (the list of tours)
Users → Guided Tours → [a tour] → Steps (the steps of one tour)
Users → Guided Tours → Options (settings + ACL)
System → Manage → Plugins → System - Guided Tours (the renderer)
The component lives at administrator/components/com_guidedtours/. The plugin that actually draws the tours lives at plugins/system/guidedtours/. Note the location: Guided Tours sits under the Users menu, next to User Actions Log, not under System.
1.4 Following a Tour as a User
As a user you do almost nothing. When a tour is available on a screen, Joomla either starts it automatically or offers it. A popover appears with a short text, a Next button, and a progress indicator such as "Step 2 of 6". You read, you click Next, and the highlight jumps to the next element. At the end you click Complete, or you can stop early with Cancel or hide a tour forever.
Back to top2. Anatomy of a Tour and a Step
Before building anything, it helps to know every field, because each one maps directly to a database column you may meet later.
2.1 The Fields of a Tour
| Field | Meaning |
|---|---|
| Title | The name shown in the list and on the intro popover. |
| UID | A unique text identifier, for example joomla-guidedtours. Joomla generates one from the title if you leave it empty. |
| Description | The HTML shown on the intro popover, before the first step. |
| URL | The page where the tour starts, as a relative URL such as index.php?option=com_content&view=articles. |
| Extensions | Which components the tour belongs to. Stored as a JSON list, for example ["com_content"] or ["*"] for everywhere. |
| Autostart | If on, the tour starts by itself the first time a user reaches its screen. |
| Access | The viewing access level, so you can limit a tour to certain user groups. |
| Language | A language tag such as en-GB, or * for all languages. |
| Status | Published, unpublished, archived, or trashed. |
2.2 The Fields of a Step
| Field | Meaning |
|---|---|
| Title | The heading of the popover. |
| Description | The body text (HTML allowed). |
| Target | A CSS selector for the element to highlight, such as #jform_title. Empty means a centered popover with no target. |
| Position | Where the popover sits relative to the target: top, bottom, left, right, or center. |
| Type | How the step behaves: Next, Redirect, or Interactive (see section 4). |
| Interactive Type | For interactive steps only, what action the user must perform. |
| URL | For redirect steps only, the page to send the user to. |
A step always belongs to one tour through its tour_id, and its place in the sequence comes from the ordering value you set by dragging rows in the steps list.
3. Creating Your First Tour
Let us build a small tour that welcomes editors to the article list. The whole job happens in the backend, with no code.
3.1 Create the Tour
- Go to
Users → Guided Toursand click New. - Set Title to "Welcome to Articles".
- Set URL to
index.php?option=com_content&view=articles. This is the screen where the tour will run. - Under Extensions, choose Articles (
com_content). - Write a short Description; it becomes the welcome popover.
- Leave Autostart off for now so you can test it on demand.
- Save.
3.2 Add the Steps
With the tour saved, open its Steps list and add steps one by one. A first useful step might be:
| Field | Value |
|---|---|
| Title | Create a new article |
| Description | Click this button to start a brand new article. |
| Target | #toolbar-new |
| Position | bottom |
| Type | Next |
Add a few more steps pointing at the search box, the filter bar, and the status column. Drag the rows to set their order.
3.3 Test It
Make sure the tour and all its steps are Published. Then visit the Articles list. Because autostart is off, you trigger the tour from Joomla's tour launcher rather than having it pop up. Walk through it, fix any target that does not highlight the right element, and only then turn on autostart if you want it to greet users automatically.
A tour is only as good as its targets. If a selector points at nothing, that step is skipped or lands in the wrong place. Always test on the real screen.Back to top
4. Step Types and Interactive Steps
Every step has a type that decides how the user moves forward. Joomla stores it as a small integer, and the three values are fixed in the component.
4.1 The Three Step Types
| Type | Value | Behaviour |
|---|---|---|
| Next | 0 | A plain informational step. The user reads it and clicks Next. |
| Redirect | 1 | Sends the user to another page (the step url), then continues the tour there. |
| Interactive | 2 | Waits for the user to actually do something on the target element before moving on. |
Use Next for "look at this" steps. Use Redirect when a tour spans more than one screen, for example moving from the article list to the article edit form. Use Interactive when you want a hands-on tutorial where the user types, clicks, or selects something themselves.
4.2 The Interactive Types
When a step is interactive, a second field, Interactive Type, says exactly what the user must do. Joomla defines six of them:
| Interactive type | Value | The user must… |
|---|---|---|
| Form Submit | 1 | Click a form's submit button. |
| Text Field | 2 | Type into a text field (optionally a required value). |
| Other | 3 | Interact with a generic field that does not fit the other types. |
| Button | 4 | Click a button. |
| Checkbox / Radio | 5 | Tick a checkbox or pick a radio option (since Joomla 5.1). |
| Select List | 6 | Choose a value from a dropdown (since Joomla 5.1). |
For a Text Field or Select step you can set a required value in the step's parameters. The tour then waits until the user enters or selects exactly that value before the Next button unlocks. This is how a tour can guide someone through filling a form correctly, not just reading about it.
Back to top5. Targeting Elements with CSS Selectors
The single most important skill for building tours is writing good targets. The target field holds a standard CSS selector, and Shepherd.js highlights whatever element it matches.
5.1 How Targets Work
Common selector styles you will use:
| Selector | Matches |
|---|---|
#jform_title |
The element with id jform_title (the Title input). |
.button-new |
Any element with the class button-new. |
#toolbar-save button |
A button inside the Save toolbar group. |
| (empty) | No target: a centered popover, good for intros and summaries. |
To find the right selector, open the screen in your browser, right-click the element, and choose Inspect. Read the id or class from the developer tools and copy it into the target field.
5.2 Position and Stability
The Position field decides where the popover sits: top, bottom, left, right, or center. Pick the side with the most free space so the popover does not cover the element it describes.
One warning about stability: Joomla's admin markup can change between versions. An id like #jform_title is reliable because Joomla forms use predictable field ids, but a deep selector that relies on a particular nesting (div > ul:first-of-type > li:last-child) can break after an update. Prefer ids and stable classes over long structural selectors.
6. Autostart and User State
Tours can start by themselves, but only once. Joomla remembers what each user did so a tour does not nag them forever. This is the trickiest part of the feature, so it is worth understanding.
6.1 The Autostart Flag
If a tour has Autostart on, Joomla looks for it when the user reaches the matching screen. If the user has not seen it yet, it starts automatically. There is also a global switch under Users → Guided Tours → Options called Allow Tour Auto Start; turn it off and no tour auto-starts anywhere, regardless of the per-tour flag.
6.2 The Three States
When a user finishes or stops an auto-starting tour, Joomla records one of three states in their user profile:
| User action | Stored state | Effect |
|---|---|---|
| Reaches the last step (Complete) | completed |
The tour never auto-starts again for this user. |
| Clicks "Hide forever" / skip | skipped |
The tour never auto-starts again for this user. |
| Closes it with Cancel | delayed |
The tour stays away for a while, then may appear again. |
The "while" for a delayed tour comes from the Delayed Time option, which defaults to 60 minutes. After that period the tour can auto-start again, which is handy for a user who closed it because they were busy, not because they were finished.
6.3 Where the State Lives
The state is saved per user in the #__user_profiles table, under a key like guidedtour.id.5 for the tour with id 5. Because it is stored against the user, a tour you completed will not bother you again, but a brand new editor still sees it fresh. If you want to test autostart repeatedly, delete that profile row for your account, or test with a different user.
7. Access, Languages and Multilingual Tours
7.1 Limiting a Tour by Access Level
Each tour has an Access level, the same viewing access levels you use for articles and modules. Set a tour to a "Managers" access level and only users in groups with that level see it. This lets you build separate onboarding for editors and for administrators on the same site.
7.2 The Language Field
A tour and its steps each carry a language tag. Set it to * and the tour shows for everyone; set it to en-GB or nl-NL and it shows only for users on that language. The plugin filters tours by the current language and the all-languages value together, so a user sees tours marked for their language plus any marked *.
7.3 How Joomla's Own Tours Are Translated
The tours that ship with Joomla, such as the "What's New" tours, do not store their text directly. Instead, their title and description fields hold language keys like COM_GUIDEDTOURS_TOUR_GUIDEDTOURS_TITLE, and Joomla translates them at display time using language files. A helper, GuidedtoursHelper::loadTranslationFiles(), loads the right language file based on the tour's UID.
For a tour you author by hand, you do not need this machinery: you simply type the text in your own language and set the language tag. The key-based system mainly matters when you build a tour that must ship translated into many languages, the way core does.
Back to top8. Under the Hood (Developer View)
Now the technical layer. Guided Tours is a clean example of a modern Joomla component plus a system plugin, and it is small enough to read in an afternoon.
8.1 The Two Tables
Everything lives in two database tables:
#__guidedtours one row per tour
#__guidedtour_steps one row per step, linked by tour_id
The key columns of #__guidedtours:
id primary key
title tour title (or a language key)
uid unique text identifier, e.g. joomla-guidedtours
description intro popover HTML (or a language key)
url relative URL of the page the tour runs on
extensions JSON list of components, e.g. ["com_content"]
autostart 0 or 1
access viewing access level
language language tag or *
published publish state
The key columns of #__guidedtour_steps:
id primary key
tour_id the parent tour
title popover heading
description popover body HTML
position top / bottom / left / right / center
target CSS selector of the highlighted element
type 0 = next, 1 = redirect, 2 = interactive
interactive_type 1..6 (only when type = 2)
url redirect target (only when type = 1)
ordering step order within the tour
params JSON, e.g. {"required":1,"requiredvalue":"Hello"}
language language tag or *
8.2 The System Plugin and Shepherd.js
The visible part of a tour comes entirely from the System - Guided Tours plugin at plugins/system/guidedtours/. It does two jobs through subscribed events:
| Event | What the plugin does |
|---|---|
onBeforeCompileHead |
Loads the Shepherd.js assets, injects translated button labels and a session token, and decides whether a tour should auto-start on this page. |
onAjaxGuidedtours |
Returns the full tour (its steps, with types mapped to strings) as JSON when the JavaScript asks for it. |
The drawing itself uses Shepherd.js, bundled under media/vendor/shepherdjs/ and wrapped by media/plg_system_guidedtours/js/guidedtours.js. Shepherd draws the popover, dims the rest of the page, and positions the highlight over the target element. When the plugin processes a tour, it maps the integer types to the strings Shepherd understands, for example step type 2 becomes interactive and interactive type 6 becomes select.
8.3 Recording State by AJAX
When the user completes, cancels, or skips an auto-starting tour, the browser calls the component's AjaxController::fetchUserState() task with three values: tid (tour id), sid (step number), and context (one of tour.complete, tour.cancel, tour.skip). The controller maps the context to a state (completed, delayed, or skipped) and saves it, but only for tours that actually auto-start.
Around that save, two events fire, which custom plugins can listen to:
onBeforeTourSaveUserState fires before the state is written
onAfterTourSaveUserState fires after, and can override the response message
This is the hook you would use to, for example, log tour completion to your own analytics, or to award a badge when a user finishes an onboarding tour.
8.4 Shipping Tours With Your Extension
Because a tour is just rows in two tables, an extension developer can ship ready-made tours inside an extension package. The user installs your component, module, or plugin, and the tours appear without any manual setup. There are two common ways to do this.
The first is an install SQL script. Joomla runs the SQL files referenced in your manifest at install time, so you add the inserts there:
INSERT INTO `#__guidedtours`
(`title`, `uid`, `description`, `url`, `extensions`,
`autostart`, `access`, `language`, `published`)
VALUES
('COM_MYEXT_TOUR_INTRO_TITLE', 'mycompany-myext-intro',
'COM_MYEXT_TOUR_INTRO_DESC',
'index.php?option=com_myext&view=items',
'["com_myext"]', 1, 1, '*', 1);
INSERT INTO `#__guidedtour_steps`
(`tour_id`, `title`, `description`, `target`, `position`,
`type`, `ordering`, `language`, `published`)
VALUES
(LAST_INSERT_ID(), 'COM_MYEXT_TOUR_INTRO_STEP1_TITLE',
'COM_MYEXT_TOUR_INTRO_STEP1_DESC', '#toolbar-new', 'bottom',
0, 1, '*', 1);
Note two things that keep the tour clean. The extensions value is a JSON array, so it must be valid JSON inside the SQL string. And the title and description hold language keys, not literal text, so you can ship the same tour translated into several languages (see section 7.3). Provide the matching strings in your extension's language files.
The second way is an installer script. If you need logic, for example to avoid duplicate inserts on reinstall or to update existing tours on upgrade, put the work in the install, update, and postflight methods of your script.php rather than in flat SQL. There you can boot com_guidedtours and use its model, which also runs the table's UID and validation logic for you:
$factory = Factory::getApplication()
->bootComponent('com_guidedtours')
->getMVCFactory();
$model = $factory->createModel('Tour', 'Administrator', ['ignore_request' => true]);
$model->save([ /* tour fields, as in section 9 */ ]);
Whichever route you choose, give every shipped tour a distinctive uid (for example mycompany-myext-intro) so it never collides with core tours or another extension's tours, and so your update script can find and refresh it later.
9. Web Services API
It is worth being clear about this, because people expect every Joomla component to have a REST endpoint. Guided Tours does not ship a Web Services API. There is no api/components/com_guidedtours/ directory, so you cannot list or create tours over the public /api/index.php/v1/ REST routes the way you can with articles or contacts.
The only HTTP entry point is the internal AJAX task described above, and it exists to record user state, not to manage tour content:
index.php?option=com_guidedtours&task=ajax.fetchUserState
&tid=5&sid=3&context=tour.complete
&[token]=1
It requires a logged-in user and a valid session token, so it is not a general-purpose API. If you need to create tours programmatically, for example to seed a fresh install, the practical routes are direct database inserts into the two tables, or booting the component and using its MVC factory:
$factory = Factory::getApplication()
->bootComponent('com_guidedtours')
->getMVCFactory();
$model = $factory->createModel('Tour', 'Administrator', ['ignore_request' => true]);
$model->save([
'title' => 'Welcome to Articles',
'url' => 'index.php?option=com_content&view=articles',
'extensions' => ['com_content'],
'published' => 1,
'language' => '*',
]);
Back to top10. SEO and Discoverability
Guided Tours is a backend onboarding tool, not public content, so it has no direct SEO footprint. A tour never appears in your sitemap, never gets indexed by Google, and produces no public URL. Do not expect to rank for anything because you built tours.
It does, however, affect a different kind of discoverability, the one that matters inside your own admin:
- Good tours make features discoverable to your clients, which cuts support questions.
- The tour URL field is the closest thing to routing: it decides which screen a tour belongs to, so set it precisely.
- If you build a frontend tour (set the extensions broadly and target frontend elements), keep the popover text short; long popovers hurt the experience on mobile.
In short, think of Guided Tours as internal documentation that lives where the work happens, not as a marketing or search asset.
Back to top11. Common Mistakes and Pitfalls
11.1 The Tour Does Not Appear
Symptom: You built a tour but nothing happens on the screen.
Fix: Check four things in order. Is the System - Guided Tours plugin enabled? Is the tour Published? Does the tour URL match the screen you are on? Does the Extensions field include the component of that screen? All four must line up.
11.2 A Step Highlights the Wrong Element
Symptom: The popover points at empty space or the wrong control.
Fix: The CSS selector in Target is wrong or matches the wrong element. Inspect the element in your browser, copy its real id or class, and prefer a stable id like #jform_title over a long structural selector.
11.3 Autostart Never Triggers Again
Symptom: The tour auto-started once, and now you cannot get it to auto-start while testing.
Fix: Joomla recorded a completed or skipped state for your user in #__user_profiles. Delete the matching guidedtour.id.N row for your account, or test with a fresh user. A delayed tour will only come back after the Delayed Time (default 60 minutes).
11.4 Autostart Works for Nobody
Symptom: No tour ever auto-starts, even brand new ones.
Fix: The global Allow Tour Auto Start option is off, or the tour's own Autostart flag is off, or the tour's Access level excludes the test user. Check all three.
11.5 A Multi-screen Tour Breaks Halfway
Symptom: The tour stops when it should move to another page.
Fix: A step that changes pages must be a Redirect step with a correct URL, and the steps that follow must target elements that exist on the new page. A plain Next step cannot cross to another screen.
11.6 The Interactive Step Will Not Unlock
Symptom: An interactive step never lets the user continue.
Fix: The Interactive Type does not match the element, or a required value is set and the user has not entered exactly that value (it is case-sensitive). Match the type to the real control and double-check the required value.
Back to top12. Best Practices
If you remember only a few things from this article, remember these:
- Keep tours short: five to eight steps beat a twenty-step marathon.
- Target by id or stable class, never by fragile deep selectors that break on upgrade.
- Always set the tour URL and Extensions so the tour only appears where it belongs.
- Use Autostart sparingly, and only for genuine first-run onboarding.
- Test autostart with a fresh user, because your own profile remembers completed tours.
- Re-check your tours after every Joomla update, since admin markup can shift.
- Use Access levels to give editors and administrators different tours on the same site.
13. Quick Reference
COMPONENT Users → Guided Tours
STEPS Users → Guided Tours → [tour] → Steps
OPTIONS Users → Guided Tours → Options
PLUGIN System → Plugins → System - Guided Tours
TABLES #__guidedtours, #__guidedtour_steps
STATE #__user_profiles (key guidedtour.id.N)
STEP TYPES 0 next, 1 redirect, 2 interactive
INTERACTIVE 1 submit, 2 text, 3 other, 4 button,
5 checkbox/radio, 6 select
POSITION top, bottom, left, right, center
LIBRARY Shepherd.js (media/vendor/shepherdjs)
AUTOSTART per-tour flag + Options → Allow Tour Auto Start
DELAY Options → Delayed Time (default 60 min)
API no REST API; internal ajax.fetchUserState only
SINCE Joomla 4.3 (April 2023)
Back to top14. Summary
Guided Tours turns Joomla into a self-teaching CMS. With nothing more than the backend, you can build interactive onboarding that highlights the right buttons, explains the right fields, and even waits for users to perform an action before moving on.
The essentials to take away:
- A tour is a container; its steps are popovers, and both are just database rows you edit in the admin.
- Steps come in three types (Next, Redirect, Interactive) with six interactive variants for hands-on tutorials.
- Targets are CSS selectors; stable ids make reliable tours.
- Autostart plus per-user state in
#__user_profilesmeans a tour greets new users once without nagging them. - The whole thing is drawn by the System - Guided Tours plugin using Shepherd.js, and there is no public REST API.
Built well, a handful of short tours can quietly remove the most common "how do I…" questions your clients ask. If you want to roll out guided onboarding across a Joomla site, or you have tours that broke after an upgrade and need a steady hand to fix the selectors, it pays to have someone who knows where every one of these pieces lives.
Back to top

Peter is a Joomla specialist and a Linux admin for fast, secure and scalable websites.


