Simple Step By Step Site Tour Plugin - Intro.js
File Size: | 226 KB |
---|---|
Views Total: | 26295 |
Last Update: | |
Publish Date: | |
Official Website: | Go to website |
License: | MIT |

Intro.js is a lightweight JavaScript library that creates step-by-step user onboarding tours for web applications.
It can help you guide users through your app's UI, highlight new features, or explaining complex workflows.
This library identifies elements through data attributes or programmatic configuration, then generates floating tooltips with navigation controls.
It manages focus states, handles keyboard navigation, and maintains tour progress through its internal state management system.
Features
- Zero Dependencies: Standalone library with no external requirements
- Lightweight: Only 10kB minified, minimal performance impact
- Dual Implementation: HTML data attributes or JavaScript API configuration
- Theme Support: Multiple built-in themes (Dark, Modern, Royal, etc.)
- Positioning System: Automatic tooltip positioning with collision detection
- Keyboard Navigation: Full keyboard support for accessibility
- Hint System: Separate hint functionality for contextual help
- RTL Support: Right-to-left language compatibility
- Mobile Responsive: Touch-friendly controls and adaptive layouts
- Event Callbacks: Comprehensive event system for custom behaviors
Install & Download
# NPM $ npm i intro.js
How to use it:
1. Include Intro.js and the required CSS files on your web page.
<!-- Core Stylesheet --> <link href="introjs.css" rel="stylesheet" /> <!-- For RTL --> <!-- <link href="introjs-rtl.css" rel="stylesheet"/> --> <!-- JavaScript --> <script src="intro.js"></script>
2. Include a theme CSS of your choice on the page. All possible themes:
- Dark
- Flattener
- Modern
- Nassim
- Nazanin
- Royal
<link href="themes/introjs-dark.css" rel="stylesheet">
3. Markup html structure. Simply using data-step
, data-intro
and data-position
to create the site tour container. All possible data attributes:
- data-intro: The tooltip text of step
- data-title: The title of the tooltip
- data-step: the number (priority) of step
- data-tooltipClass: the CSS class for tooltip
- data-highlightClass: the CSS class for the helperLayer
- data-position: top, left, right, bottom (default), bottom-left-aligned (same as bottom), bottom-middle-aligned, bottom-right-aligned or auto
- data-scrollTo: the element to scroll to
- data-disable-interaction: disable interactions with elements inside the highlighted box
<div data-step="1" data-intro="Content 1">Feature #1</div> <div data-step="2" data-intro="Contetn 2" data-position='right'>Feature #2</div> <div data-step="3" data-intro="Contetn 3" data-position='left'>Feature #3</div>
4. Start the tour.
// Starts the tour for all elements with data-intro introJs().start(); // Or, scope the tour to a specific container introJs(".myContainer").start();
5. Customize your tour by passing the following options to the setOptions method.
introJs.tour().setOptions({ /* Define your tour steps here. For example steps: [{ title: 'Welcome', intro: 'Hello World!' }, { intro: '<img src="1.webp" onerror="this.onerror=null;this.src="1.gif" alt="">' }, { element: document.querySelector('.card-demo'), i ntro: 'This step focuses on an element' }] */ steps: [], /* Is this tour instance active? Don't show the tour again if this flag is set to false */ isActive: true, /* Next button label in tooltip box */ nextLabel: "Next", /* Previous button label in tooltip box */ prevLabel: "Back", /* Skip button label in tooltip box */ skipLabel: "×", /* Done button label in tooltip box */ doneLabel: "Done", /* Hide previous button in the first step? Otherwise, it will be disabled button. */ hidePrev: false, /* Hide next button in the last step? Otherwise, it will be disabled button (note: this will also hide the "Done" button) */ hideNext: false, /* Change the Next button to Done in the last step of the intro? otherwise, it will render a disabled button */ nextToDone: true, /* Default tooltip box position */ tooltipPosition: "bottom", /* Next CSS class for tooltip boxes */ tooltipClass: "", /* Start intro for a group of elements */ group: "", /* CSS class that is added to the helperLayer */ highlightClass: "", /* Close introduction when pressing Escape button? */ exitOnEsc: true, /* Close introduction when clicking on overlay layer? */ exitOnOverlayClick: true, /* Display the pagination detail */ showStepNumbers: false, /* Pagination "of" label */ stepNumbersOfLabel: "of", /* Let user use keyboard to navigate the tour? */ keyboardNavigation: true, /* Show tour control buttons? */ showButtons: true, /* Show tour bullets? */ showBullets: true, /* Show tour progress? */ showProgress: false, /* Scroll to highlighted element? */ scrollToElement: true, /* * Should we scroll the tooltip or target element? * * Options are: 'element' or 'tooltip' */ scrollTo: "element", /* Padding to add after scrolling when element is not in the viewport (in pixels) */ scrollPadding: 30, /* Set the overlay opacity */ overlayOpacity: 0.5, /* To determine the tooltip position automatically based on the window.width/height */ autoPosition: true, /* Precedence of positions, when auto is enabled */ positionPrecedence: ["bottom", "top", "right", "left"], /* Disable an interaction with element? */ disableInteraction: false, /* To display the "Don't show again" checkbox in the tour */ dontShowAgain: false, dontShowAgainLabel: "Don't show this again", /* "Don't show again" cookie name and expiry (in days) */ dontShowAgainCookie: "introjs-dontShowAgain", dontShowAgainCookieDays: 365, /* Set how much padding to be used around helper element */ helperElementPadding: 10, /* additional classes to put on the buttons */ buttonClass: "introjs-button", /* additional classes to put on progress bar */ progressBarAdditionalClass: ""; /* Optional property to determine if content should be rendered as HTML */ tooltipRenderAsHtml: true; }).start();
6. API methods available.
addStep addSteps appendFloatingElement callback clone currentStep decrementCurrentStep disableKeyboardNavigation disableRefreshOnResize enableKeyboardNavigation enableRefreshOnResize exit getCurrentStep getCurrentStepSignal getDirection getOption getRefreshesSignal getStep getSteps getTargetElement goToStep goToStepNumber hasStarted incrementCurrentStep isActive isEnd isLastStep nextStep onafterchange onAfterChange onbeforechange onBeforeChange onbeforeexit onBeforeExit onchange onChange oncomplete onComplete onexit onExit onskip onSkip onstart onStart previousStep refresh resetCurrentStep setCurrentStep setDontShowAgain setOption setOptions setSteps start
7. Add hints to elements:
<button data-hint="Click here to save your work" data-hint-position="top">Save</button>
introJs().addHints();
8. Possible options for the hints.
introJs.hint().setOptions({ /* List of all HintItems */ hints: [], /* True if the Hint instance is set to active */ isActive: true, /* Default tooltip box position */ tooltipPosition: "bottom", /* Next CSS class for tooltip boxes */ tooltipClass: "", /* Default hint position */ hintPosition: "top-middle", /* Hint button label */ hintButtonLabel: "Got it", /* Display the "Got it" button? */ hintShowButton: true, /* Hints auto-refresh interval in ms (set to -1 to disable) */ hintAutoRefreshInterval: 10, /* Adding animation to hints? */ hintAnimation: true, /* additional classes to put on the buttons */ buttonClass: "introjs-button", /* Set how much padding to be used around helper element */ helperElementPadding: 10, /* To determine the tooltip position automatically based on the window.width/height */ autoPosition: true, /* Precedence of positions, when auto is enabled */ positionPrecedence: ["bottom", "top", "right", "left"], /* Optional property to determine if content should be rendered as HTML */ tooltipRenderAsHtml: btrue, }).addHints();
9. API methods for the hints.
addHint addHints callback clone destroy disableCloseDialogOnWindowClick disableHintAutoRefresh enableCloseDialogOnWindowClick enableHintAutoRefresh getActiveHintSignal getHint getHints getOption getRefreshesSignal getTargetElement hideHint hideHintDialog hideHints isActive isRendered onhintclick onHintClick onhintclose onHintClose onhintsadded onHintsAdded refresh removeHint removeHints render setHints setOption setOptions showHint showHintDialog showHints
See also:
- jQuery Feature Tours Plugin - Joyride
- Crumble - Web Site Feature Tour Plugin
- Feature Walkthrough Plugin For jQuery and YUI - introtour-ui
- 10 Best Tour Plugins To Guide Visitors Through Your App
FAQs
Q: How do I prevent a tour from running every time a user visits the page?
A: Use the dontShowAgain
option in your configuration. Alternatively, for more control, use the oncomplete
callback to set a flag in localStorage
. Then, before you call .start()
, check if that flag exists.
Q: Can I use dynamic or HTML content inside a tooltip?
A: Yes. The intro
property in a step object can contain an HTML string. Just make sure the tooltipRenderAsHtml
option is set to true
. This is useful for embedding images or links directly into the tour steps.
Q: Can I customize the appearance of tooltips and highlights?
A: Yes. You can modify colors, fonts, borders, and animations by overriding the default styles or using the built-in theme system.
Q: How do I handle dynamic content that loads after page initialization?
A: Call introJs().refresh()
after new content loads to update element positions and recalculate positioning. For single-page applications, reinitialize the tour when route changes occur.
Q: Does intro.js work with shadow DOM elements?
A: Standard intro.js doesn't directly support shadow DOM targeting. You'll need to manually query shadow DOM elements and pass them to the steps configuration rather than using data attributes.
Q: Can I prevent users from skipping certain steps?
A: You can control navigation through the onBeforeChange
callback, returning false
to prevent step advancement. Combine this with conditional logic to enforce required actions before progression.
Q: How do I handle tours in responsive layouts?
A: Enable autoPosition: true
to automatically adjust tooltip positioning based on viewport size. The library recalculates positions on window resize, but you may need to call refresh()
for complex layout changes.
Q: Is it possible to show multiple tours on the same page?
A: Yes, create separate intro.js instances with different selectors or step configurations. Use the group
option to organize related steps and manage multiple tour states independently.
Q: Can I integrate intro.js with React or Vue components?
A: Intro.js works with any JavaScript framework.
Q: Is Intro.js free for commercial use?
A: No. It's AGPL-licensed, meaning it's free for open-source and personal projects. For a commercial website, application, or plugin, you need to purchase a license.
Changelog:
v8.3.2 (2025-07-14)
- Bugfixes
- Update Doc
v8.3.1 (2025-07-07)
- Bugfixes
- Convert the library to use Signals and reactive elements
v7.2.0 (2023-08-15)
- Bugfix
v7.1.0 (2023-08-14)
- Refactoring the folder structure and improving types
- feat: adding typescript type declarations
- bugfixes
v7.0.1 (2023-03-26)
- Bug Fix
v7.0.0 (2023-03-26)
- Bug Fix
- Move to Typescript
v6.0.0 (2022-07-10)
- feat: async/await style callbacks and functions
- Correct position of skip button when having multiline titles
v5.1.0 (2022-04-05)
- feat: "Don't show again" feature
- feat: Adding pagination's "of" label to options
v5.0.0 (2022-02-07)
- fix: data attrs must be separated with a hyphen
- Adding ESM + minifying all assets by default
v4.3.0 (2021-11-07)
- Hint show/hide flag
- Hint CSS improvements
- Bug Fix
- fix: scroll top position for fixed elements
- fix:hint live refresh
v4.2.0 (2021-08-28)
- fix: scroll top position for fixed elements
v4.1.0 (2021-06-18)
- feat: updating the bullets layer after refresh(true)
- fix: exit() should not throw an exception if the parent elements are removed
v4.0.0 (2021-06-13)
- refactoring the introForElements function
v3.4.0 (2021-03-25)
- Fixing the overlay layer for position relative/sticky targets
- Fixesed: Positioning breaks when passing relatively-positioned element to introJs()
- Fix for setting left style checkRight.js
v3.3.1 (2021-02-07)
- Adding autoPosition option
v3.2.1 (2020-12-20)
- Bug Fix
v3.2.0 (2020-12-17)
- Bug Fix
v3.1.0 (2020-02-13)
- feat: adding title field to intro items
- fix(babel): updating the browser support
- feat: box-shadow background
- fix(intro): adding hasAttribute
2020-02-13
- Fixed calculating tooltip bottom position
v2.9.3 (2018-07-20)
- hotfix to skipping and exiting the intro
This awesome jQuery plugin is developed by usablica. For more Advanced Usages, please check the demo page or visit the official website.