Views Tabs turns a Drupal View into a tabbed interface — the first field becomes each tab's label, and every other field renders inside that tab's pane — built in vanilla JavaScript with four tab positions and deep linking. It is a Views style plugin, machine name vvjt, with no jQuery dependency.
Two ways to use it
Most sites use Views Tabs the obvious way: horizontal or vertical labeled tabs, where a visitor clicks a label to switch panes. But because the "label" is just the first field in the row, it does not have to be text — set it to an image field and you get a row of clickable image thumbnails that switch the visible content underneath, without writing a line of JavaScript yourself.
Requirements
| Requirement | Value |
|---|---|
| Drupal core | ^11.3 || ^12 |
| PHP | 8.3+ |
| Core modules | Views, Filter |
| Contributed dependency | VVJ Core — required by every VVJ v2 module, pulled in automatically by Composer |
The 2.x branch does not run on Drupal 10. If you are on Drupal 10, install the 1.x series instead; if the version gap itself is the obstacle, upgrading Drupal to 11 or 12 is work I do.
Row structure
Set the row style to Fields with at least two fields. Every view built with this plugin carries the CSS class vvj-tabs alongside js-view-dom-id. The first field becomes the tab's clickable label and should not itself be a link — the module falls back to disabling any link on it automatically, but it is cleaner to avoid one. Every field after the first is grouped into that row's tab pane. The currently open tab's button carries the CSS class active.
Configuration
| Setting | Controls |
|---|---|
| Tabs position | Top, right, bottom or left |
| Animation | None, zoom, opacity fade, or slide from top, bottom, left or right |
| Max width / max height | Caps the size of tab buttons (useful for vertical tabs) and of the button container |
| Available breakpoint | 576, 768, 992, 1200 or 1400px — the width at which vertical tabs collapse to horizontal |
| Wrap tabs | Wrap buttons onto multiple lines instead of the default auto-scroll when they exceed the available space |
| Background colors | Independent colors for the tab buttons and the tab panes, or disable both |
| Enable CSS library | Turn the shipped stylesheet off for full custom styling |
Deep linking
Views Tabs can enable deep linking with a URL identifier of your choosing, so a specific tab is reachable and shareable by URL fragment rather than always opening on the first one — useful when a tabbed FAQ, product spec sheet or documentation page is linked to from outside the page itself.
JavaScript API
Every tab group is reachable through Drupal.vvjt, addressed by its deep-link identifier, a CSS selector, or a direct element reference:
Drupal.vvjt.goToTab('features', 3);
Drupal.vvjt.getCurrentTab('features');
Drupal.vvjt.getTotalTabs('features');
Drupal.vvjt.getInstance('#vvjt-12345'); //
Drupal.vvjt.getAllInstances();
That is enough to drive a tab group from an external menu, jump to a tab based on a filter selection, or coordinate two tab groups on one page.
Accessibility
Views Tabs implements ARIA roles and state properties so assistive technology announces which tab is selected, full keyboard navigation so tabs can be operated without a mouse, and focus management that keeps the currently selected tab focused for keyboard and screen reader users.
Custom tokens in Views header and footer
With Global: Text area or Global: Unfiltered text and "Use replacement tokens from the first row" enabled, Drupal's default tokens will not resolve — use the module's own instead. {{ title }} becomes [vvjt:title], {{ field_image }} becomes [vvjt:field_image], and appending :plain strips HTML, as in [vvjt:title:plain]. Complex rewrite expressions with embedded tokens are not supported; reference individual fields instead. In v2, resolution runs through the shared vvj_core.token_resolver service, with the same token syntax as v1.
Installation
composer require drupal/vvjt
drush en vvjt -y
drush cr
Then edit your view, choose Views Vanilla JavaScript Tabs as the format, and set the position, animation and breakpoint under Format Settings.
Using more than one field as the tab label
The label reads from a single field by default. To combine several, add all the fields you need and mark each "Exclude from display," then add a Custom Global Field (Text) that uses Views' replacement-pattern tokens to merge them into one label. Order the excluded fields first, the custom global field second, and the remaining pane content after that.
A known limitation
Views Tabs does not support the Views Grouping Field feature. Grouping rows by a field is not compatible with the current implementation, so avoid combining the two.
Common questions
Can the tab label be an image instead of text?
Yes. The first field can be any field type, including an image field, which turns the tab row into a set of clickable thumbnails.
What happens to vertical tabs on a narrow screen?
They collapse to horizontal tabs at your configured responsive breakpoint, so a left- or right-positioned tab set never squeezes a phone-width layout.
Can I link directly to one tab?
Yes, once deep linking is enabled with a URL identifier — the tab is then reachable and shareable by URL fragment.
Will it install on Drupal 10?
No — 2.x requires Drupal 11.3 or later, or Drupal 12. Use the 1.x branch on Drupal 10.
Do I need to install VVJ Core myself?
No. It is a required dependency and Composer installs it automatically when you require drupal/vvjt.
Related modules
Views Tabs is one of ten Views display styles sharing the VVJ Core foundation. For an accordion-style expanding list instead of tabs, see Views Accordion; for a two-sided card, see Views Reveal; for a sequential slideshow, see Views Slideshow. If your content is built with Paragraphs Bundles, its Tabs paragraph type uses the same underlying pattern without a view.
Need tabs built into a real site?
Views Tabs is free and GPL-licensed, like all my contributed work. If you want a tabbed spec sheet, FAQ or thumbnail gallery built around it, or a Drupal 10 to 11/12 upgrade so you can run the 2.x branch, that is my day job. Read about my Drupal services, see what a Drupal developer handles day to day, or get in touch.