Is there an embeddable signup form?

We use a direct to a cupon, but i think you can just add /suscribe to your homepage

and you can use a link to your portal page


I’m trying this but still no success. Where exactly should I put this code? Also, do I need to keep these brackets: {youradmindomain} ?

You actually can do this using a trick. Zapier can create members. On my friend’s website, I had to integrate a google form for people who want to endorse in his political party. That meant having two separate “sign in” forms, one for newsletters and member-only content and one for endorsment. I wanted to link them. In the end, making the form “member only” and injecting the individual’s email in the form was way more complicated than it shoudl and I happily found that zapier can use goofle forms (and other forms providers) to create new members on ghost ; no matter where the form itself is located.

So you can actually do that. Just create a zap linking ghost and google forms. That’s not as clean as on might want but with a bit of styling, it can look nice.

Any news on this? I still only see hacky ways to do this.
This is what keeps me from moving to Ghost from Substack…

Embedding the portal again is risky, one of my use cases is having a ghost blog with its own membership, but I’d like to add my newsletter subscription to some posts, which is another dedicated ghost publication (the newsletter).

Other platforms provide easy embeddable iframes.

If you want to embed a frame, you can just do something like:

<iframe src="https://YOUR_GHOST_DOMAIN/#/portal/signup" style="border: none; width: 300px; height: 400px;"></iframe>

See demo at ghost frame embed - JSFiddle - Code Playground

For anyone that hasn’t been able to figure this out (as it takes some HTML knowledge to put the documentation together with this thread), the most basic way to create a custom form on another site is something like:

<script defer src="" data-ghost="https://YOUR_GHOST_DOMAIN" data-api="https://YOUR_GHOST_DOMAIN/ghost/api/content/" data-key="YOUR_GHOST_CONTENT_API_KEY"></script>
<form data-members-form>
  <input type="email" required data-members-email />
  <button type="submit">Continue</button>

I like to even add a label based on which site it’s embedded on:

  <input type="hidden" data-members-label value="YOUR_LABEL" />

But this is actually just for sending the email and will not change anything after submitting the form, so you really have to add something like:

<strong class="feedback">Check your inbox (and maybe the spam folder) for an activation link.</strong>

form .feedback {
	display: none;

form.success input, form.success button {
	display: none !important;

form.success .feedback {
	display: unset;

See a demo that puts it all together (although you’d have to copy/paste it somewhere else to work completely).

I have many project websites that have a signup form pointing to the same ghost install, for example on my personal site—it works well so far and let’s me have one instance to manage everything.


Trying to implement the solutions here and basically copied the code posted by @rosano above. However I keep getting a CORS error and I can’t understand why.

Access to fetch at 'https://MYGHOSTDOMAIN/members/api/member/' from origin 'https://SECONDDOMAIN' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

I’m on Ghost Pro and the only reference I can find to this in the API documentation is that I have to make sure to use the * address for my site, which I am. Other responses I’ve seen indicate that the API should be configured to allow all origins, so does anyone know why I might be getting this error?

1 Like

I have found that sometimes what shows up as a CORS error in the browser is actually a ‘not found’ error (real inconsiderate design there…). So you might want to check the network tab of your browser dev tools / console to see the error code and to get more details (here’s a guide for Chrome). I could be wrong but I have a feeling the paths usually start with /api or /ghost and not /members/.

That’s weird if that’s the problem because it seems to be trying to fetch /members/api/member/ on its own. This is what my script tag looks like:

<script defer src="" data-ghost="https://GHOST_ADMIN_DOMAIN" data-api="https://GHOST_ADMIN_DOMAIN/ghost/api/content/" data-key="CONTENT_API_KEY"></script>

Ghost sites running Portal do make a call to the /members endpoint to figure out if the user is logged in (& change button styles accordingly, I think?). Here’s my ghost pro site:

As you can see, it gets back access-control-allow-origin: *, which should mean that you can call that endpoint from anywhere without a CORS problem.

What does your network tab look like in dev tools? Are you sure this is the call throwing the cors error?

Thanks – I didn’t know to look there. But it would appear there isn’t a CORS problem here, access-control-allow origin is correct.

It seems that there’s actually a redirect error? This is from my console:

api.js:26 GET https://GHOSTADMINDOMAIN/members/api/member/ net::ERR_FAILED 302

Your image is just the download on the portal.

I’m not sure on the 302.

I see. There’s nothing on the network tab that’s even loading from my Ghost site

EDIT: Disregard, I found this

Does it literally say GHOSTADMINDOMAIN or your actual domain name?

It says my * domain, which I just didn’t want to post.

302 is a temporary redirect. There should be a Location header in the HTTP 302 response of the URL it will try next.

OK I found this. There’s no access-control-allow-origin here though. It seems like it’s redirecting from my admin domain to my regular domain. Could the discrepancy be why it’s throwing a CORS error?

EDIT: I figured this out. I needed to use my regular domain for data-ghost and my admin domain for data-api. This is what my script tag should have been:

<script defer src="" data-ghost="" data-api="" data-key="699593c3a30c3a6f2376e2f14a"></script>


Glad you figured it out! :) Thanks for reporting back.

Adding this to the external site is now adding the “subscribe” button from the bottom right corner of my Ghost site to the other site.

Now there is a built-in solution:

1 Like