New Free Plugin: Browser Timezone and Locale

This is a little utility element I built to support my forthcoming set of Server-Side Action plugins. All this little guy does is return the browser’s Timezone and Locale information, so you can do fetch the user’s Timezone ID and language preferences dynamically.

Useful for a variety of things around date manipulation and internationalization. (For example, if locale is “fr”, you might want to present things en français.) The element’s value’s return the other basic date/time localization that you might find useful as well.

In the simple demo app, I use this to format Current Date/Time based on the user’s Timezone ID and Locale fetched from the browser, using one of my server-side actions. (On the backend, Moment Timezone’s locale features are used to format the date as a string, written in the user’s preferred language.)

Simple simple demo and instructions:


nice thanks

1 Like

The demo displays missing element?

Yes, it does. I’m using the demo page for other things and simply haven’t updated the plugin info to point somewhere else. Hardly needs a demo though: you just drop this on your page and it spits out the documented values at its outputs. Nothin’ fancy! Simple and effective.

The above demo page is old. You could visit here, @mattblake, if you want to see it working:

… and then the editor can be viewed here (nothing much to see here, I ping a custom server-side plugin to format the date via moment):

(The point being that basically the plugin spits out a locale string [amongst other things]… it’s then up to you to do with it as you please.)

1 Like

Hey @keith can this plugin tell you the GMT time difference as well as the users location? I’ve linked up Google calendar but the time is wrong for the UK and using this I could adjust the time on the calendar events. Thanks

Hi Dudley: 1. Note - you don’t need this plugin if you are using CG Pro in a page. User Timezone detection is built in to that and reported at the outputs. (And is potentially more accurate as it uses moment to do it.)

What BTZ&L reports is like this:

Timezone ID: America/Los_Angeles
Locale: en-US
Browser Calandar: gregory
Browser Day Format: numeric
Browser Month Format: numeric
Browser Numbering System: latn
Browser Year Format: numeric

Note also that there are some new Utility functions in CG Pro that can help you transform dates from one timezone to another, if that’s a need that you have. Video docs on that to come, though you can likely figure them out from the in-plugin and in-action documentation! :slight_smile:

I’m not quite sure what you mean by this:

What’s the issue you’re having, more precisely?


Hey Keith, thanks for getting back to me. Glad CGP has this built in and I don’t need to use another plugin. Using CGP I convert the date time to ISO format to link with Google calendar. Let’s say I pick today at 10:00 am when the event is pulled into my Google calendar it shows as 11:00 am. Can PM you instead to take it off this thread. Thanks

This is what the TIMEZONE ID field is for: It lets you construct your dates in the target timezone, not the stupid browser timezone. :wink:

The CG Pro element shown below will spit out dates in UTC, for example:

If the timezone ID field is empty, CG Pro works like most other date/time pickers – it’ll spit out dates in the browser timezone, whatever that is.

When the timezone ID field is set, any blocked dates you supply are interpreted as being from that timezone as well. (So, you see you don’t have to convert anything. If you ingest all blocked dates [for example] in UTC, everything is hunky dory.)

Now, you can get really fancy with this if you like and the timezone ID can of course be dynamic. In my app, I actually store a given vacation rental’s reservations in that rental’s timezone. (Some might argue this is a stupid thing to do, but I have reasons.)

So, when we look at a GRUPZ calendar, we are looking at – and picking dates in – the property’s timezone, whatever it may be. The user is none-the-wiser.

Here for example, is a sample booking widget: Booking Widget for BLUE BELL KNOLL TEST 1

The imaginary vacation rental whose availability is displayed here is “located” in America/New_York timezone ID. If the user picks – for example – the 26th thru 28th of this month, the dates generated are August 26th at 0 hours in EDT to August 28th at 0 hours in EDT, even though me and my browser are in America/Los_Angeles.

This is a core part of the magic of Calendar Grid Pro. :slight_smile:

1 Like

You are a magician Keith! just checked and it worked perfectly!

1 Like

Hey @keith! Awesome plugin, thanks!

I’m able to retrieve the locale (e.g. es_es) on page load with your plugin, and save it in a “language” field for the user (even if the visitor is not signed up, so there’s no real visitor on the database). I’ve lowercased the locale provided by your plugin and substituted dashes with underscores for that locale, so that “es-ES” becomes “es_es” (what Bubble seems to detect as a language). This successfully retrieves the language of the user.

Also, I’ve translated from English to Spanish all the texts on my app from the Settings tab, after setting the field “Language field on the user type” to “language” (the field in which I save the output from your plugin).

So, when a user loads the page, the locale is detected on page load and the language is saved for that user, regardless of the user being logged in or not (cool!). The issue is, to display the translated texts, the user needs to refresh the page to re-load the texts the detected language (the texts are not updated on the fly).

The question is: Is there a way to update the texts visible on page once the language is detected without having to force a page refresh? Thanks for the help!

Instead of using App Text, you could set the text in the conditions tab. This way it will update the texts without page refresh, but might come with other problems for you.

1 Like

Thanks a lot for the idea, @reger-alexander! Indeed, that alternative is going to add a lot of complexity for the maintenance of a multi-language app, so I’d like to avoid it… Even worse, with conditions I could not use the translated texts stored in the Settings tab (Languages), but I’d have to translate the texts inside the conditions. There must be a way to refresh the texts on the fly when a user field changes…

Do you have a problem with the fact, that the user himself has to refresh the page, or generally that a page refresh is needed?

Because you could force the page to refresh automatically when the field is changed. Like having the current users language field as default value in a group, and have an action which reloads the current page when this value is changed.

Actually I think most sites on the internet are refreshing when you change the language, aren’t they.

1 Like

Hey @reger-alexander! That makes the job done, thank you so much! It’s a bit meeeeh that the user has to experience a refresh when his language is different from the app’s default one (English in case of my app) after having spend almost 1 second on page. That could lead to a bad UX that could have an impact in bounce rate and other KPIs.

This is even worse when you bring paid users (e.g. through Facebook ads), as you’d be paid for clicks that then bounce. Also, not sure if Google Analytics will track the pageview twice, before and after the refresh (although this is something that could be avoided using JS to track events only after the refresh step passes). But for now, I think it’s the closest thing to a decent solution for multi-language apps! :slight_smile:

It would be AWESOME if Bubble would allow text updates on the fly after language detection, or a kind of refresh for specific groups only.

Hi, @keith

Is this plugin working now?
It seems that the plugin can not detect the Locale(language setting) for now.
It used to be perfectly fine until recently.


Hey @keith, same issue than @rio; The Locale doesn’t work. It’s showing as “numeric” like the date formats:

Hi @julienallard1 (also @rio): This is apparently a bug in the Bubble plugin editor (which has surely broken many simple plugins). I’ve fixed the issue for Browser Timezone and Locale by moving state publishing up to the code initialize level, instead of relying on Bubble’s “state initialization” routines.

To fix, just update your Browser Timezone and Locale plugin to version 1.1.0. (And post here if you have any additional problems.)

Sorry to hear that this has been broken for so long. I’ll be posting a rant and reporting this formally to Bubble. Shit like this pisses me off.

Detail for bug report:

All this plugin does is stuff like:

return Intl.DateTimeFormat().resolvedOptions().timeZone

e.g., (screenshot):

Open your browser console (hit F12) and enter this command:


You’ll see the time zone returned properly.

So, what seems to be happening is Bubble plugins are not calling their state initialization routines – or at least, not all of them.

(Since most plugins, with some notable exceptions (e.g., my advanced plugins), use these techniques it’s fair to say that pretty much all basic Bubble plugins are broken right now. Surprise, surprise, right? This would seem to be yet another very serious Bubble bug that apparently nobody bothered to report.)

@allenyang @eve and whoever, take note

You can see this quite clearly as here’s a version of the Browser Timezone & Locale plugin that prints console logs whenever any of the initialization routines are hit:

But in the console, all we see is:

So, as you can see, only the last initialization routine is being called (they should all be called)… and that routine is somehow being called twice. Nice, right?

Anyway… ranting aside… to fix your issue, upgrade to version 1.1.0 of the BTZ&L plugin. But, again, this isn’t MY bug, it’s a Bubble bug.


Ok this may seem like a stupid question. But did your try the following

Initializing the result in a variable then returning it. It’s good practice to not return a action directly.

Also do you function take time to execute. Should you be using async await or a promise

Also did you try returning a simple static string or number

Dude, seriously? If you have plugins that rely on state init functions, they are currently broken: