Ghost Portal / Members (Pro)

Keep Ghost's membership widget active on your static site so subscribers can sign in and pay — while your Ghost backend stays hidden from public search engines.

How it works

Your static site serves all public content from the main domain. Ghost Portal runs as a popup — when a visitor clicks Subscribe or Sign In, the popup authenticates against your Ghost backend on a subdomain. After login, paying members are redirected to the Ghost backend to read gated content.

How do I enable Ghost Portal in SnapStatic?
  1. Open the Pro Generator and go to the Advanced step.
  2. Enable the Ghost Portal / Members toggle.
  3. Generate your site — portal.min.js is kept in the static output.
Important: Ghost Make site private must be OFF. Private mode blocks member logins on your Ghost backend. Use robots.txt to hide it from search engines instead (see below).
Domain setup: static site on main domain, Ghost on subdomain

Example: example.com → static site, ghost.example.com → Ghost backend

  1. In Ghost Admin → Settings → General, set your site URL to https://ghost.example.com.
  2. In the SnapStatic wizard: Source Domain = https://ghost.example.com, Generated Domain = https://example.com.
  3. Enable Ghost Portal in the Advanced step.
  4. Generate and deploy the static site to example.com.
  5. In Ghost Admin → Settings → Portal, set the sign-in redirect URL to https://ghost.example.com so paying members land on the Ghost backend after login to access gated posts.
Static site:    https://example.com         → all public posts, pages
Ghost backend:  https://ghost.example.com   → member login, paid content, Ghost Admin
Hide Ghost backend from search engines (SEO)

Prevent duplicate content by blocking search engines from indexing the Ghost subdomain. Use two layers:

1. robots.txt via Nginx

Add to your Ghost backend's Nginx config, inside the server block:

location = /robots.txt {
    add_header Content-Type text/plain;
    return 200 "User-agent: *\nDisallow: /\n";
}

2. noindex meta tag

In Ghost Admin → Settings → Code Injection → Site Header, add:

<meta name="robots" content="noindex, nofollow">

Both layers together ensure search engines ignore the Ghost subdomain even if robots.txt is bypassed.

Nginx: redirect Ghost frontend, keep member auth working

Optional. Redirects all public frontend visits from the Ghost subdomain to your static site, while keeping Ghost Admin, member login, and API endpoints accessible. Logged-in members (detected via session cookie) are served directly from Ghost.

Add this to the http block (outside the server block) in your Nginx config:

map $cookie_ghost_members_ssa $is_member {
    default 0;
    ~.+     1;
}

Then in your server block for the Ghost subdomain:

server {
    server_name ghost.example.com;

    # Ghost Admin, member auth, API, assets — always accessible
    location ~ ^/(ghost|members|content)/ {
        proxy_pass http://localhost:2368;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # robots.txt — block search engines
    location = /robots.txt {
        add_header Content-Type text/plain;
        return 200 "User-agent: *\nDisallow: /\n";
    }

    # Frontend — serve for logged-in members, redirect others to static site
    location / {
        if ($is_member = 0) {
            return 302 https://example.com$request_uri;
        }
        proxy_pass http://localhost:2368;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Replace ghost.example.com and example.com with your actual domains. Reload Nginx after changes: nginx -t && systemctl reload nginx

Testing the setup
  1. Portal buttons visible — visit your static site main domain. Subscribe and Sign In buttons should appear in the theme header/footer.
  2. Portal popup opens — click Subscribe or Sign In. The Ghost Portal popup should open without errors. Check browser console for no CORS errors.
  3. Sign-in works — complete a test login. After login the redirect should take you to ghost.example.com.
  4. Paid content accessible — as a logged-in member, navigate to a member-only post on the Ghost subdomain. Content should be visible.
  5. SEO check — visit https://ghost.example.com/robots.txt. Should return Disallow: /. Visit ghost.example.com directly — should redirect to example.com (if Nginx redirect is configured).
  6. Ghost Admin accessible — visit https://ghost.example.com/ghost/. Should load normally (not redirected).
If Portal popup fails: confirm Ghost private mode is OFF in Ghost Admin → Settings. Private mode blocks Portal authentication.