Forum Documentation Showcase Pricing Learn more

Require Login To View Page?

How do I require the user to be logged in to view pages? The only solutions I’ve found seem very jenky or they’re workarounds. I don’t want users to allow access to pages unless they’re logged in (this doesn’t seem like a complicated request). Meaning, I don’t want the user to have access to a page for a brief second then redirect them… I just don’t want them to have access at all. These are the methods I’ve tried that don’t work:

  1. Use the on page load then redirect if user isn’t logged in.
  2. Use general > when user isn’t logged in > redirect.
  3. Use on condition true > redirect.
  4. Use groups to hide content on the page unless a user is logged in.
  5. Use privacy rules to prevent users from viewing data unless they’re logged in.

None of these work because the user can access a page without being logged in, then they’re redirected.

Hey @caseyfueller, does that mean that you want to show 404 page in this case ?

My proposal:
show pop up login window on page load (only if user is not logged in) …
worked for me (although my use case was bit different)

First: You don’t have to navigate the user/agent away from the page.

Second: ATM, you can’t have exactly what you desire, because this is just the way Bubble implements routing.

Third: You can do what other web apps do, which is to not actually navigate at all, but to emulate navigation. (read on)

Could Bubble implement routing by a different method? Sure, but then that would be a different interface and Bubble is designed with this metaphor of access control being associated with “actions” on a page.

[Aside: In an environment geared toward users who know little-to-nothing about how the web works (much less web applications) I can only imagine the questions that would crop up here in the forums and that alone is reason enough to not desire such features.]

You will note that we do not have any sort of granular server control in Bubble (examples: granular control of allow X-Frame-Options, you can’t have myappurl.domain/[user_id] etc., etc.). It’s just not a thing.

The “stack” for your Bubble app does not have its own server (unless you are on a dedicated plan – and even then, you probably don’t have control over it through any UI, though you probably can have Bubble configure it for special requests). You share a cluster with many other apps – there is some sort of serving/routing that decides, when a request comes in for some URL (either a page in your/somebody else’s app or your/somebody else’s API endpoint) that decides when the response will be served.

And neither is there a concept of a “virtual router” in your app beyond the design of your page flows. (Though it’s worth noting that a Bubble app’s folder hierarchy is flat – there are no subfolders, e.g., myappurl.domain/products/best-brands-of-child-repellent is not a thing, right? So your “pages” may or may not be virtual, but they are probably virtual, so I guess we could have a fake routing interface, but see the point above and the point I am about to make below.)

Now, in today’s web, and in today’s development environments, some are familiar with the “fake” routing of things like React Router (which give you the ability to create a single-page app that seemingly “navigates” to new URLs but in fact stays put in the context of the current page, but that also allows the handling of incoming requests for these fake URLs).

Well, vanilla Bubble just doesn’t have that. At least, it’s not exposed in the way that things like React Router do it. (And building single-page apps in Bubble is so kooky that I’m surprised anybody does it, but to each their own, eh?)

However, the equivalent in Bubble is this:

As I said, you don’t have to navigate the agent away from the page. You can include your login element in a resusable on the page. In the classic Bubble template, there’s a great example of this. The login/signup dialog is a reusable that is, itself, included in the reusable page header, so all your pages can be “/login” if you choose to tweak it a bit.

How can you do this?

Well, for authorized-user-only-pages you group everything except for the header in a group that is not visible on page load (the smart way to do this is create your starting template page with a group on it and build all your shit in that group, NOT in the page object – in the demos I link to below, this group is given the HTML ID PAGEGROUP). This group, of course, is NOT visible on page load.

And then, on page load, you evaluate “user is logged in” / “user is not logged in”. If the user is logged in, you show the “page group” (I usually call this group something like “Page Proxy”).

If the user is not logged in, you SHOW THE LOGIN POPUP. For extra credit you can do the same stupid shit that React Router does and change the visible URL in the browser’s nav bar to whatever/login (in the demo linked below I’m using Copilot’s “Browser” plugin, which I don’t find any faults with - it’s just a nice, clean interface to the browser API we need to interact with here to do this).

Once you do that (create “fake” /login pages) you should actually create page /login so that if some smartypants refreshes their browser, they will land on the ACTUAL /login page.

I’m not gonna type out how you do all that here, but just point you to a sample:

Run Mode – You have to sign up/log in to access this page:

When you get there, you will note that it seems you’ve landed on a page called /login. But you haven’t. Of course, if you refresh your browser, you WILL wind up on /login. (So we gotta create a real page for /login in Bubble if we’re gonna fake this easily.)

But don’t do that. Don’t reload the page. Just signup/login and watch what happens. Without REALLY navigating you to another page, all of a sudden the hidden page group gets added to the DOM, AND the apparent URL changes to the original page you requested.


(Note: Does that sound hinky to you? It’s literally how zillions of web apps built with code work. So which is hinky: the Bubble way or the React Router way? :thinking: Answer: Neither – it’s just how web apps work.)

Edit mode for this demo page (“you-gotta-log-in”):

Edit mode for the Header element, where some of this magic needs to be handled (displaying the login popup if we’re on the you-gotta-log-in or login pages… we wouldn’t need to “conditionalize” that if we were doing this for every page in our app, we would instead adopt conditions for the pages on which we DON’T require the user to be logged in, right?):

Edit mode for the real /login page (to handle the case if the user lands on a login-only page, and we rewrite their URL and they then refresh):

Please note: the sample app here is one of my demo apps for List Shifter. It was not designed to do the right magic on all the pages and, besides the demo page(s) I’m talking about here, is not designed to fake URLs all over the place. I just did this quick lil’ demo to help you understand. (Also, having done it, I kind of like this approach and might adopt it in real apps, so there’s that.)


  1. Some stuff that seems hinky is actually the way things work in real life. (This can be said of just about everything in real life, amirite?)

  2. Despite your complaints, Bubble does real page routing. You just don’t have super-granular control over it. Also, said routing is brokered by a server or cluster of servers that are shared and - especially on free and lower-tier paid plans - it FEELS like request brokering is WAY TOO SLOW. [I’ve not seen the folks at Bubble address what actually happens here, so I’m educated guessing, but this is a frustration about Bubble in general and it would be interesting to know exactly how much capacity you have to buy to get priority. Hmm.]

  3. A lot of times, on the interweb, you think you’re being routed for realz, but you’re not. (Instead, the page is actually doing that and you’re not navigating in the true sense of the word. And we can do this in Bubble if we desire to.)

  4. It’s really hard to tell the difference between 1 and 2, beyond apparent speed. (And, done right, there should be no way for you as the user to know.)

  5. Rolling your own fake routing is kind of a pain in the butt in Bubble (hmm… is there perhaps a plugin opportunity here?), but to do it for a small set of pages isn’t that big of a deal, should you desire to. (I sometimes think of Bubble as a Rapid Development Environment, but then my hands get tired of all the pointing and clicking and I’m like “WHAT SADIST DESIGNED THIS???”)

  6. You might initially think that #4 is a strong argument for just saying “fuck it” and learning modern web app development with the tools that a million times more people use than Bubble, but really it’s all kind of the same. (And also you’re using Bubble because you realize that you can get quite a bit further along, quite a bit faster than having to learn everything about web development before you can even build “Hello World”. Also, if you think Bubble is crazy, just dig into modern front-end web development… it’s a fucking HAT full of crazy… but not without its advantages. :man_shrugging:)

  7. I did not call this out, but: BTW, remember that PAGEGROUP group I mentioned before? If you load the /you-gotta-log-in page without being logged in, you will note that PAGEGROUP element DOES NOT EXIST in the page. It’s literally not in the DOM yet. When we login, PAGEGROUP gets created. If we now logout, PAGEGROUP becomes not visible, but only because its CSS display property goes to none. That is, it is still present in the page but not being rendered.

(This would argue for doing a REAL navigate to some safe page on log out, rather than just faking the page’s logged out state. I’ve actually never tested that before and am a little surprised that the element is not destroyed. Practically speaking, this probably isn’t a big security risk, but it points out the importance of using privacy rules for protecting data, and not just visibility.)

  1. Related reading and exploration: Direct links for users?
1 Like

@keith, where do I sign up for your newsletter/blog? lol - Your posts are always witty, informative, and long enough for me to enjoy my coffee while my hands recuperate from all the clicking and pointing. :point_up:

Just wanted to say thanks for your contributions to the community. I’m sure newbies and even long term bubblers all appreciate the efforts. :nerd_face:


Hey, @lantzgould, thanks for the kind comments.

(And, I’m always heartened when someone understands my sense of humor. There are those that think I’m a dick, but I’m actually simply the sort of person who has only a limited set of responses to questions and, roughly speaking those responses are as follows: (0) ** stares blankly **, (1) “your question is stupid, needs to be called out as stupid, and deserves no further discussion”, (2) “your question is stupid but reminds me that…” [INSERT LONG RESPONSE], (3) “good question” [NO RESPONSE FOLLOWS], (4) “good question, the answer is:” [SHORT, POSSIBLY INCORRECT RESPONSE FOLLOWS], or (5) “good question and this reminds me that…” [LONG RESPONSE FOLLOWS].)

I’d love to do a newsletter or blog, but the audience for Bubble stuff is just ridiculously small. (There are others who do no-code podcasts and projects and such that are more expansive and cover more solutions and make a go at it, but I literally actually feel that nearly every other no/low-code thing is just a STUPID SACK OF SHIT, so I’ve nothing to talk about but Bubble.)

Anyhoo, if you enjoy my ramblings, there IS a way to show your appreciation:, where you can pay-what-you-will for my time and energy on anything that strikes your fancy!

(And, BTW, I don’t [usually] just take those contributions and buy crack with them. Karma-Ware contributions keep me motivated to make great new stuff. Real world example, someone did actually save List Shifter from going paid. Of course, then I went out and spent that money on crack, but that Karma-Ware crack let me power thru the most recent video demos about List Shifter. So it’s a win-win sort of situation, right?)


[Edit: I kind of do have a podcast, but instead of being a regularly-scheduled podcast, it’s just me posting irregularly-scheduled videos here in the forums. I act when the muse strikes me.]

1 Like