Where'd my Portal go?

Is your floating "membership button" missing from Ghost, especially on mobile?

A confused looking Ghost.

A while back (I think it was version 5.107), the Ghost team changed the floating portal (membership) button to being off by default, and always off on mobile.

Off by default is no big deal, because you can turn it on. Always off on mobile is a bit more of a challenge, because a some themes don't include a 'subscribe' link. So, what do you do if your theme now needs a subscribe link?

Very very easiest fix (maybe): Update your theme

If you are running an older official theme, it's probably been updated to have a menu bar button to replace the absent floating button. If you haven't customized your theme, try updating. If you're running a paid or custom theme, you could try reaching out to the theme developer to see if they have updated their theme to give you a button on mobile.

Your link should go to #/portal/. Access your sitewide navigation from /ghost > settings (gear icon) > navigation.

Slightly more complicated option: Edit the theme.

The problem with the 'easy' fix above is that it means everyone gets whatever label you pick for the link, whether they're signed in or not.

If you can edit your theme, you can add a link. The code will look something like this, and would go somewhere in the code that generates your Ghost header. (The code below is taken from the Headline theme.)

{{#if @site.members_enabled}}
    <div class="gh-head-members">
        {{#unless @member}}
            {{#unless @site.members_invite_only}}
                <a class="gh-head-link" href="#/portal/signin" data-portal="signin">Sign in</a>
                <a class="gh-head-btn gh-btn gh-primary-btn" href="#/portal/signup" data-portal="signup">Subscribe</a>
            {{else}}
                <a class="gh-head-btn gh-btn gh-primary-btn" href="#/portal/signin" data-portal="signin">Sign in</a>
            {{/unless}}
        {{else}}
            <a class="gh-head-btn gh-btn gh-primary-btn" href="#/portal/account" data-portal="account">Account</a>
        {{/unless}}
    </div>
{{/if}}

Want your floating button back? No problem!

Here's some code that can go at the end of default.hbs:

{{#unless @member}}
    <a href="#/portal/" class="join-hover-button">
       <div class="hover-button-inner ">
          {{>"icons/newspaper"}}
          <span>&nbsp;{{@site.portal_button_signup_text}}</span>
        </div></a>
{{/unless}}  

I'm actually grabbing the portal sign-up text from the portal configuration page. Currently I have the newspaper icon hard-coded (because I had to build the svg into the theme, but this could be changed...

And some styles to go with it:

<style>
    .join-hover-button {
        position: fixed;
        bottom: min(32px, 5vw);
        right: min(32px, 5vw);
        z-index: 1000;
        border-radius: 32px;
        background-color: var(--ghost-accent-color);
        padding: 16px 24px;
        box-shadow: 0 0 8px rgba(0,0,0,0.5);
    }
    .join-hover-button:hover {
        background-color: hsl(from var(--ghost-accent-color) h calc(s - 20) calc(l + 10));
        opacity: 1;
    }
    .hover-button-inner {
        color: #fff;  
        display: flex;
        flex-direction: row;   
    }
    .join-hover-button a svg {margin-right: 4px;}
    @media (max-width: 600px) {
        .join-hover-button span {
            display: none; 
        }
        .join-hover-button {
            padding: 16px;
        }
        
    }
</style>

I've chosen to only show the floating button to people who aren't yet subscribed/signed-in, because it does take up quite a bit of room.

❔
Isn't there some code injection that'll just make the portal button reappear for users on mobile?

I thought there should be, and then I looked at the code. The button (and the whole iframe that should be triggered by it) doesn't exist in the DOM on mobile, unfortunately. It's not visibility: hidden or display: none. It's just completely not rendered. Changing the visibility of the portal button would unfortunately require a fork of Portal. So hopefully you like one of the solutions above, because maintaining a fork is kind of a pain!

Other odds and ends

  • âœĻI updated my membership page to let you pick the topics you're interested in! It uses Ghost labels to segment users by interest, so that I can (eventually) send a newsletter to just the users interested in a particular topic. If you need some similar segmentation for your site, please let me know! (Next up: Actually figuring out what those segments should be. And maybe writing a post about it.)
  • 🎉 The one-year anniversary of my switch to doing Ghost development as my full-time job is this month. Thanks to everyone who helped to make it an awesome year.
  • 🌐 For those of you interested in Ghost translation, I've got an issue open about incorrect variable use in translation files. 👉Dozens of languages with errors. Help appreciated, as always! No technical skill needed.
  • 📰 A shout-out to the folks at Tiny News Collective. I'm doing some member support and theme updates for them, and they've got a bunch of new Ghost publications they're incubating. Very cool project, and I love getting to support so many local journalists.

Hey, before you go... If your finances allow you to keep this tea-drinking ghost and the freelancer behind her supplied with our hot beverage of choice, we'd both appreciate it!