View Full Version : (3) Instant Notifications in Page Title like Facebook
findingpeace
03-07-2013, 06:17 PM
Using javascript and AJAX, we have implemented a system that updates notifications for likes, subscribed threads, and PM's in the page title, similar to Facebook. We use it on our site:
http://psychopathfree.com/forum.php
It updates live, so even if they're visiting another site and the tab is sitting idle, they will see new notifications popup instantly.
It's not very good coding, and I'm sure there is a better way to do it :) But if anyone would like this on their site, let me know. I would be happy to share our method.
In the past day alone of enabling it, we've seen a 400+% increase in user engagement, new posts, new activity, and online users.
vimarc
03-07-2013, 06:45 PM
Hi I checked your site but didn't find.
findingpeace
03-07-2013, 06:48 PM
Hey marc, the notifications will only show up for registered users who have a notification - I can post an example screenshot here:
https://vborg.vbsupport.ru/external/2013/03/48.png
vimarc
03-09-2013, 09:26 AM
hi thanks..
which donate mod you are using?
FTG LIQUID CL
03-09-2013, 11:02 PM
I would like to have this!
findingpeace
03-10-2013, 09:48 PM
I would like to have this!
Hi FTG - which mods do you currently use that utilize the notifications system? (ie. Recent Thanks, Subscribed Thread Notifications, etc?)
Thanks :)
FTG LIQUID CL
03-12-2013, 08:04 PM
VSA advanced new post
Cel Social Groups Notifications
deltahawk5
03-13-2013, 04:59 AM
Woah, I'd love to have this.
I have DBTech Advanced Tagging and Thanks for Post (Hippy Fix) with Notifications.
findingpeace
03-13-2013, 09:08 PM
Hi all,
Okay so here is the code I use, but it'll be different of course depending on what notifications mods you use. I would also definitely recommend getting the DBTech AJAX vbNotifications mod, since it will align perfectly with the instant title updates. It automatically detects & integrates both of the mods you guys have mentioned. Otherwise, users will be getting the (#) notification but still need to refresh the page to see it in the old vBulletin notifications bar.
I have chosen to put it in FORUMHOME, FORUMDISPLAY, SHOWTHREAD, and USERCP_SHELL. You could do it in any template you want these to be visible. Just keep in mind, it operates on a 30 second Javascript timer, so it will partially boost your page requests. I definitely wouldn't put it in a global template (like footer or something). It needs to be placed somewhere in the head tag.
<script type="text/javascript">
setInterval(function() {
var data = "{vb:raw relpath}";
$.get(document.location.toString()).then(function (data){
//find and set the title of the page
document.title = data.match(/<title>(.+)<\/title>/)[1];
});
}, 30000);
setTimeout(function() {
var data = "{vb:raw relpath}";
$.get(document.location.toString()).then(function (data){
//find and set the title of the page
document.title = data.match(/<title>(.+)<\/title>/)[1];
});
}, 1000);
</script>
This does two things: 1) Sets a 30 second timer (you can change this to whatever you want) to refresh the notifications. 2) Sets a single-time, 1-second timeout to refresh the notifications upon page load, in case they've updated since the click.
In each of these pages, you will also need to set the new initial Page Title. This will be different for each template you modify. For example, the Title element of USERCP_SHELL should be modified to look like this:
<title><vb:if condition="$title_note_count">({vb:raw title_note_count}) </vb:if>{vb:raw pagetitle} - {vb:raw vboptions.bbtitle}</title>
The bold part is the added change. You can add that as a prefix to any of the page titles and it will show the notifications in the title.
Now the part that will be different for everyone: $title_note_count
This is the variable I'm pushing to my templates through a plugin / hook. It's the current total notification count. Depending on what mods you're using, your code will probably be different than mine. Here's an example of the plugin I use:
Hook: process_templates_complete
Execution Order: 5
global $vbulletin;
$currentuserid = $vbulletin->userinfo[userid];
$query = "SELECT * FROM vbuser WHERE userid = $currentuserid";
$result = $vbulletin->db->query($query);
while($row = $vbulletin->db->fetch_array($result)) {
$a = $row['friendreqcount'];
$b = $row['vmunreadcount'];
$c = $row['socgroupinvitecount'];
$d = $row['socgroupreqcount'];
$e = $row['pcunreadcount'];
$f = $row['vbseo_likes_unread'];
$h = $row['pmunread'];
$i = $row['recent_thankcnt'];
}
$title_note_count = $a + $b + $c + $d + $e + $f + $h + $i;
vB_Template::preRegister('FORUMHOME',array('title_ note_count' => $title_note_count));
vB_Template::preRegister('SHOWTHREAD',array('title _note_count' => $title_note_count));
vB_Template::preRegister('recent_thanks',array('ti tle_note_count' => $title_note_count));
vB_Template::preRegister('FORUMDISPLAY',array('tit le_note_count' => $title_note_count));
vB_Template::preRegister('USERCP_SHELL',array('tit le_note_count' => $title_note_count));
vB_Template::preRegister('newthread',array('title_ note_count' => $title_note_count));
vB_Template::preRegister('newreply',array('title_n ote_count' => $title_note_count));
I use this code because the vbNotifications mod disables the "Total Notifications" variable. If you don't use that mod, you can probably much more easily grab the total notifications by just registering the existing variable in the same hook as above, without all the database calls:
$vbulletin->userinfo['notifications_total'] = $notifications_total;
Let me know how this works, and I will stick around here to help out as much as I can :) Also, if anyone knows a better way to push notifications with AJAX, feel free to post! The timer isn't the best idea in the world, but my server's resources are 100% fine running 30 seconds. I even experimented with 5 seconds and found no performance issues.
FTG LIQUID CL
03-14-2013, 08:32 PM
I cant seem to get this to work.I dont use vbNotifications,where does the last piece of code go?
findingpeace
03-14-2013, 08:48 PM
The last part would go in a new plugin (ignore the a, b, c, d plugin) like this:
Hook: process_templates_complete
Execution Order: 5
$vbulletin->userinfo['notifications_total'] = $title_note_count;
vB_Template::preRegister('FORUMHOME',array('title_ note_count' => $title_note_count));
vB_Template::preRegister('SHOWTHREAD',array('title _note_count' => $title_note_count));
vB_Template::preRegister('recent_thanks',array('ti tle_note_count' => $title_note_count));
vB_Template::preRegister('FORUMDISPLAY',array('tit le_note_count' => $title_note_count));
vB_Template::preRegister('USERCP_SHELL',array('tit le_note_count' => $title_note_count));
vB_Template::preRegister('newthread',array('title_ note_count' => $title_note_count));
vB_Template::preRegister('newreply',array('title_n ote_count' => $title_note_count));
FTG LIQUID CL
03-15-2013, 04:52 PM
OK I will give this a try.
--------------- Added 1363366543 at 1363366543 ---------------
Do I leave out the entire first plugin or just the a,b,c,d, part?
findingpeace
03-15-2013, 06:28 PM
Yeah just leave out the first plugin entirely - that's if you need to recalculate everything, which you shouldn't if you don't have the vbNotifications mod :)
FTG LIQUID CL
03-15-2013, 08:25 PM
Ok great ,Im gonna go test this out!
dizzynation
03-15-2013, 10:54 PM
Ok, can you clarify if you are not using th DB tech mod then what code do we use exactly?
findingpeace
03-16-2013, 01:01 AM
Yep! This one:
https://vborg.vbsupport.ru/showpost.php?p=2410029&postcount=11
The rest of it is all the same as the first post (adding the Javascript & titles into Templates). The only difference is the plugin - sorry for the confusing posts :)
FTG LIQUID CL
03-16-2013, 01:47 PM
I cant seem to get this to work,I am using 4.1.12. I used the same templates as you.Does it matter where I put the code in these templates
findingpeace
03-16-2013, 02:23 PM
JS should always be in the header tag, so as long as it's somewhere in there! Test to see if the JS is working, simply by changing it to this code:
<script type="text/javascript">
setInterval(function() {
var data = "{vb:raw relpath}";
$.get(document.location.toString()).then(function (data){
//find and set the title of the page
document.title = "Test2";
});
}, 30000);
setTimeout(function() {
var data = "{vb:raw relpath}";
$.get(document.location.toString()).then(function (data){
//find and set the title of the page
document.title = "Test";
});
}, 1000);
</script>
Load the relevant page, and the page title should change to "Test" after 1 second, and "Test2" after 30 seconds
FTG LIQUID CL
03-16-2013, 02:59 PM
I dont see anything changing to test or test 2,I must be doing something wrong?
--------------- Added 1363447219 at 1363447219 ---------------
I changed this
<title>{vb:raw vboptions.bbtitle}</title>
to this
<title><vb:if condition="$title_note_count">({vb:raw title_note_count}) </vb:if>{vb:raw pagetitle} - {vb:raw vboptions.bbtitle}</title>
is this correct?
findingpeace
03-16-2013, 03:42 PM
Yes, that is 100% correct, but the JS not changing your title immediately is a problem - are you putting the script code in that same template? It can go right below the <title> tag
FTG LIQUID CL
03-16-2013, 05:51 PM
Im gonna try putting the js code right below the <title>tag!
findingpeace
03-16-2013, 06:29 PM
Im gonna try putting the js code right below the <title>tag!
Cool :) let me know if that at least gets the title changing! That part should work, even without the hook plugin
FTG LIQUID CL
03-16-2013, 07:53 PM
Here is wht my forumdisplay template looks like,the blue is what I changed and added.Is this right or wrong?
{vb:stylevar htmldoctype}
<html xmlns="http://www.w3.org/1999/xhtml"<vb:if condition="$vboptions['enablefacebookconnect']"> xmlns:fb="http://www.facebook.com/2008/fbml"</vb:if> dir="{vb:stylevar textdirection}" lang="{vb:stylevar languagecode}" id="vbulletin_html">
<head>
{vb:raw headinclude}
<title><vb:if condition="$title_note_count">({vb:raw title_note_count}) </vb:if>{vb:raw pagetitle} - {vb:raw vboptions.bbtitle}</title>
<script type="text/javascript">
setInterval(function() {
var data = "{vb:raw relpath}";
$.get(document.location.toString()).then(function (data){
//find and set the title of the page
document.title = "Test2";
});
}, 30000);
setTimeout(function() {
var data = "{vb:raw relpath}";
$.get(document.location.toString()).then(function (data){
//find and set the title of the page
document.title = "Test";
});
}, 1000);
</script>
<script type="text/javascript" src="clientscript/vbulletin_read_marker.js?v={vb:raw vboptions.simpleversion}"></script>
<vb:if condition="$vboptions['storecssasfile']">
{vb:cssfile forumhome-rollup.css}
<vb:else />
{vb:cssfile forumbits.css,forumhome.css,options.css}
</vb:if>
<!--[if lt IE 8]>{vb:cssfile forumbits-ie.css,options-ie.css}<![endif]-->
<vb:if condition="$show['sidebar']">
{vb:cssfile sidebar.css,widgets.css,tagcloud.css}
<!--[if lt IE 8]>{vb:cssfile sidebar-ie.css}<![endif]-->
<script type="text/javascript">
<!--
document.write('<script type="text/javascript" src="' + yuipath + '/animation/animation-min.js?v={vb:raw vboptions.simpleversion}"></script>');
var sidebar_align = '{vb:raw show.sidebarposition}';
var content_container_margin = parseInt('{vb:math {vb:stylevar forum_sidebar_width}+{vb:math {vb:stylevar padding}*2}}');
var sidebar_width = parseInt('{vb:stylevar forum_sidebar_width}');
//-->
</script>
<script type="text/javascript" src="{vb:raw vboptions.bburl}/clientscript/vbulletin-sidebar.js?v={vb:raw vboptions.simpleversion}"></script>
</vb:if>
{vb:raw headinclude_bottom}
</head>
<body>
{vb:raw header}
{vb:raw navbar}
<div id="pagetitle">
<h1>{vb:raw vboptions.bbtitle}</h1>
<p id="welcomemessage" class="description">{vb:rawphrase welcome_to_the_x, {vb:raw vboptions.bbtitle}}</p>
</div>
<vb:if condition="$show['sidebar']">
<div id="content_container" class="{vb:raw $sidebar_class} <vb:if condition="$show['sidebarposition'] == 'left'">contentright</vb:if>">
<div id="content" <vb:if condition="$sidebar_class">class="{vb:raw $sidebar_class}"</vb:if>>
</vb:if>
<!-- main -->
{vb:raw template_hook.forumhome_above_forums}
<ol id="forums" class="floatcontainer">
{vb:raw forumbits}
</ol>
{vb:raw template_hook.forumhome_below_forums}
<!-- /main -->
<div class="navlinks">
<a href="{vb:raw $vboptions.vbforum_url}{vb:if "$vboptions['vbforum_url']", '/', ''}forumdisplay.php?{vb:raw session.sessionurl}do=markread&markreadhash={vb:ra w bbuserinfo.securitytoken}" rel="nofollow">{vb:rawphrase mark_forums_read}</a>
<vb:if condition="$vboptions['forumleaders']">|
<a href="showgroups.php{vb:raw session.sessionurl_q}" rel="nofollow">
<vb:if condition="$vb_suite_installed">
{vb:rawphrase view_site_leaders}
<vb:else />
{vb:rawphrase view_forum_leaders}
</vb:if>
</a></vb:if>
</div>
{vb:raw ad_location.board_after_forums}
<!-- what's going on box -->
<div id="wgo" class="collapse wgo_block block">
<h2 class="blockhead">{vb:rawphrase whats_going_on}</h2>
<div class="blockbody formcontrols floatcontainer">
{vb:raw template_hook.forumhome_wgo_pos1}
<vb:if condition="$show['loggedinusers']">
<!-- logged-in users -->
<div id="wgo_onlineusers" class="wgo_subblock section">
<h3 class="blocksubhead"><img src="{vb:stylevar imgdir_misc}/users_online.png" alt="{vb:rawphrase currently_active_users}" />{vb:rawphrase currently_active_users}</h3>
<div>
<p>{vb:rawphrase there_are_x_y_online_link, {vb:raw totalonline}, {vb:raw session.sessionurl_q}} <span class="shade">{vb:rawphrase x_members_and_y_guests, {vb:raw numberregistered}, {vb:raw numberguest}}</span></p>
<p>{vb:rawphrase most_users_ever_online_was_x_y_at_z, {vb:raw recordusers}, {vb:raw recorddate}, {vb:raw recordtime}}</p>
<vb:if condition="$activeusers">
<ol class="commalist" id="wgo_onlineusers_list">
<vb:each from="activeusers" value="loggedin">
{vb:raw post.signature}
{vb:stylevar dirmark} <a class="username" href="{vb:link member {vb:raw loggedin}}">{vb:raw loggedin.musername}</a>{vb:raw loggedin.invisiblemark}{vb:raw loggedin.buddymark},
</vb:each>
</ol>
</vb:if>
</div>
</div>
<!-- end logged-in users -->
</vb:if>
{vb:raw template_hook.forumhome_wgo_pos2}
<vb:if condition="$show['upcomingevents']">
<div id="wgo_events" class="wgo_subblock section">
<h3 class="blocksubhead"><img src="{vb:stylevar imgdir_misc}/event.png" alt="{vb:rawphrase todays_events}" /><vb:if condition="$show['todaysevents']">{vb:rawphrase todays_events}<vb:else />{vb:rawphrase upcoming_events_for_the_next_x_days, {vb:raw vboptions.showevents}}</vb:if></h3>
<ol>
{vb:raw upcomingevents}
</ol>
</div>
</vb:if>
{vb:raw template_hook.forumhome_wgo_pos3}
<vb:if condition="$show['birthdays']">
<!-- today's birthdays -->
<div id="wgo_birthdays" class="wgo_subblock section">
<h3 class="blocksubhead"><img src="{vb:stylevar imgdir_misc}/birthday.png" alt="{vb:rawphrase todays_birthdays}" />{vb:rawphrase todays_birthdays}</h3>
<ol class="commalist">
<vb:each from="birthdays" value="row">
<li><a href="{vb:link member, {vb:raw row}}">{vb:raw row.username}</a><vb:if condition="$row['age']"> ({vb:raw row.age})</vb:if>{vb:raw row.comma}</li>
</vb:each>
</ol>
</div>
<!-- end today's birthdays -->
</vb:if>
{vb:raw template_hook.forumhome_wgo_pos4}
<div id="wgo_stats" class="wgo_subblock section">
<h3 class="blocksubhead"><img src="{vb:stylevar imgdir_misc}/forum_stats.png" alt="{vb:rawphrase x_statistics, {vb:raw vboptions.bbtitle}}" />{vb:rawphrase x_statistics, {vb:raw vboptions.bbtitle}}</h3>
<div>
<dl>
<dt>{vb:rawphrase threads}</dt>
<dd>{vb:raw totalthreads}</dd>
<dt>{vb:rawphrase posts}</dt>
<dd>{vb:raw totalposts}</dd>
<dt>{vb:rawphrase members}</dt>
<dd>{vb:raw numbermembers}</dd>
<vb:if condition="$show['activemembers']">
<dt>{vb:rawphrase active_members}</dt>
<dd>{vb:raw activemembers}</dd>
</vb:if>
</dl>
<p>{vb:rawphrase welcome_to_our_newest_member_x, {vb:link member, {vb:raw newuserinfo}}, {vb:raw newuserinfo.username}}</p>
{vb:raw template_hook.forumhome_wgo_stats}
</div>
</div>
<div id="wgo_legend" class="wgo_subblock section">
<h3 class="blocksubhead"><img src="{vb:stylevar imgdir_misc}/legend.png" alt="{vb:rawphrase icon_legend}" />{vb:rawphrase icon_legend}</h3>
<div>
<dl id="icon_legends" class="icon_legends">
<dt><img src="{vb:stylevar imgdir_statusicon}/forum_new-16.png" alt="{vb:rawphrase new_posts_forum}" /></dt><dd>{vb:rawphrase new_posts_forum}</dd>
<dt><img src="{vb:stylevar imgdir_statusicon}/forum_old-16.png" alt="{vb:rawphrase no_new_posts_forum}" /></dt><dd>{vb:rawphrase no_new_posts_forum}</dd>
<vb:if condition="$vboptions['showlocks']"><dt><img src="{vb:stylevar imgdir_statusicon}/forum_lock-16.png" alt="{vb:rawphrase forum_is_closed_for_posting}" /></dt><dd>{vb:rawphrase forum_is_closed_for_posting}</dd></vb:if>
<dt><img src="{vb:stylevar imgdir_statusicon}/category-16.png" alt="{vb:rawphrase category_forum}" /></dt><dd>{vb:rawphrase category_forum}</dd>
<dt><img src="{vb:stylevar imgdir_statusicon}/forum_link-16.png" alt="{vb:rawphrase link_forum}" /></dt><dd>{vb:rawphrase link_forum}</dd>
{vb:raw template_hook.forumhome_icon_legend}
</dl>
</div>
</div>
{vb:raw template_hook.forumhome_wgo_pos5}
</div>
</div>
<!-- end what's going on box -->
{vb:raw ad_location.board_below_whats_going_on}
<vb:if condition="$show['sidebar']">
</div>
</div>
<div id="sidebar_container" class="<vb:if condition="$show['sidebarposition'] == 'left'">sidebarleft</vb:if><vb:if condition="$close_sidebar"> sidebar_closed</vb:if>">
<a id="sidebar_button_link" href="#">
<vb:if condition="$show['sidebarposition'] == 'left'">
<img id="sidebar_button" src="{vb:stylevar imgdir_misc}/<vb:if condition="$close_sidebar">tab-expanded-left.png<vb:else />tab-collapsed-left.png</vb:if>" alt="" />
<vb:else />
<img id="sidebar_button" src="{vb:stylevar imgdir_misc}/<vb:if condition="$close_sidebar">tab-expanded.png<vb:else />tab-collapsed.png</vb:if>" alt="" />
</vb:if>
</a>
<ul id="sidebar" <vb:if condition="$close_sidebar">class="sidebar_hidden"</vb:if> >
{vb:raw sidebar}
</ul>
</div>
</vb:if>
<script type="text/javascript">
<!--
vbphrase['doubleclick_forum_markread'] = "{vb:rawphrase doubleclick_forum_markread}";
init_forum_readmarker_system();
//-->
</script>
{vb:raw footer}
</body>
</html>
--------------- Added 1363464615 at 1363464615 ---------------
i see test showing in the page tab now but it does not change to test 2?
findingpeace
03-16-2013, 08:31 PM
Awesome! That means the script stuff is working fine now - you can remove the blue code - now we just have to figure out how to grab the total notifications count for you :) Check out this thread, which was my original source for the idea:
https://vborg.vbsupport.ru/showthread.php?t=281435
This should give you an idea of how to code the plugin
--------------- Added 1363466412 at 1363466412 ---------------
OH! Here's the problem - need to call bbuserinfo if you're using the non-vbNotifications method. I'm so sorry for such an awful explanation :)
Here is what I would do for the title:
<title>({{vb:raw bbuserinfo.title_note_count}) {vb:raw pagetitle} - {vb:raw vboptions.bbtitle}</title>
I'm testing without the vb:if conditional right now - that way we can rule out the conditional as a source of the problem.
FTG LIQUID CL
03-16-2013, 10:06 PM
I will give this a try now!
--------------- Added 1363539840 at 1363539840 ---------------
I noticed my page title now loks like this ({)
Anyone tried this on vB 4.2.5? Does not seem to work for me.
Working fine for me on 4.2.5
I added the plugin
Hook: process_tempates_complete
Title: Notifications
Order: 5
Code:
$vbulletin->userinfo['notifications_total'] = $notifications_total;
Then in FORUMHOME, FORUMDISPLAY, SHOWTHREAD I added the following code before the title tag.
<vb:if condition="$show['member']">
<script type="text/javascript">
setInterval(function() {
var data = "{vb:raw relpath}";
$.get(document.location.toString()).then(function (data){
//find and set the title of the page
document.title = data.match(/<title>(.+)<\/title>/)[1];
});
}, 30000);
setTimeout(function() {
var data = "{vb:raw relpath}";
$.get(document.location.toString()).then(function (data){
//find and set the title of the page
document.title = data.match(/<title>(.+)<\/title>/)[1];
});
}, 1000);
</script>
</vb:if>
Then edited the start of the title tag to add this.
<vb:if condition="$show['member'] AND $bbuserinfo[notifications_total]">({vb:raw bbuserinfo.notifications_total}) </vb:if>
Forum home example below.
<title><vb:if condition="$show['member'] AND $bbuserinfo[notifications_total]">({vb:raw bbuserinfo.notifications_total}) </vb:if>{vb:raw vboptions.bbtitle}</title>
Addition mods I'm using that work with this:
Subscribed threads in notifications (https://vborg.vbsupport.ru/showthread.php?t=267329)
FractalizeR: Show items, awaiting moderation in notifications area (https://vborg.vbsupport.ru/misc.php?do=producthelp&pid=fr_notifymoditems4)
Advanced user tagging (https://vborg.vbsupport.ru/showthread.php?threadid=242733)
Thanks for the confirmation. The plugin is working for me, but the javascript fails. It shows this at the top of the page:
(.+)<\/title>/)[1]; }); }, 1000);
I'll attach it in a text file, try copy and pasting it from there.
Edit
Or try this minified version.
<script type="text/javascript">setInterval(function(){$.get(document.location.toS tring()).then(function(t){document.title=t.match(/<title>(.+)<\/title>/)[1]})},3e4),setTimeout(function(){$.get(document.loca tion.toString()).then(function(t){document.title=t .match(/<title>(.+)<\/title>/)[1]})},1e3);</script>
I tried removing the quotation marks from var data = "{vb:raw relpath}"; and the error is gone. But the notification number in the title did not update.
Do you know what is the use of relpath in this script?
I've no idea, I just copied the script off this page.
I've just tried adding the code to a new 4.2.5 base skin and it's only auto updating on showthread, it works fine on all my skins but they have an older base skins - I wonder if something has been changed that stops the JS running?
Anyway, I'm going to continue to see if I can get it running on a fresh skin and will report back if I do.
Got it, it needs jquery (all my normal skins had it).
<vb:if condition="$show['member']">
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script type="text/javascript">setInterval(function(){$.get(document.location.toS tring()).then(function(t){document.title=t.match(/<title>(.+)<\/title>/)[1]})},3e4),setTimeout(function(){$.get(document.loca tion.toString()).then(function(t){document.title=t .match(/<title>(.+)<\/title>/)[1]})},1e3);</script>
</vb:if>
Thank you. Adding jquery link solves the issue.
I have also tried adding favicon notification to the tab, as given here http://lab.ejci.net/favico.js/
I have also tried adding favicon notification to the tab, as given here http://lab.ejci.net/favico.js/
I spent days down that rabbit hole and couldn't get it fully working :p
vBulletin® v3.8.12 by vBS, Copyright ©2000-2025, vBulletin Solutions Inc.