Is there an embeddable signup form?

I’d like to embed the signup form for a ghost site on other sites - e.g. other ghost or static webpages. I can design the form, that’s not a problem, but I don’t know where to submit the form. Is there an API-based workaround (with CORS)?

4 Likes

We really need this

Yes, please give us this feature.

You can embed portal JS forms on any domain
(edit data-ghost attribute value to include your ghost install location)

<script defer src="https://unpkg.com/@tryghost/portal@~0.15.0/umd/portal.min.js" data-ghost="https://yourghostdomain.com"></script>

Portal will then work the same as on your local Ghost site, and you can built HTML forms that post to Ghost in the same way you can in themes.

We plan to create more paths for this in future - but there aren’t many people experimenting with it yet, so it requires some willingness to do some tinkering/exploration

5 Likes

I would like to swap the embedded form of another service with my Ghost installation and am wondering if any of these options are possible (to avoid adding JavaScript interactions on my page):

  • hard-coding the form action so that it redirects to the portal and sends the magic link after arriving at Ghost
  • setting the email via the portal URL https://yourghostdomain.com/#/portal/signup?email=someone@example.com
  • setting a label via the portal URL, like https://yourghostdomain.com/#/portal/signup?label=alfa

This really does need a bit more attention and clarity for users to be able to embed signups in all their other outlets. Critical for building membership.

With Ghost 5.0, there have been a few changes to this. To make Portal run on a non-Ghost site, you need to include the script as follows.

<script defer src="https://unpkg.com/@tryghost/portal@latest/umd/portal.min.js" data-ghost="https://yourghostdomain.com" data-api="https://{youradmindomain}/ghost/api/content/" data-key="CONTENT_API_KEY"></script>

To get a Content API Key, generate one in the Custom Integration section in Admin, the docs for this are here: Content API JavaScript Client

(I ran into an issue with the earlier implementation, the above solution was provided to me by Ghost support so I thought I’d cross-post here)

6 Likes

Is there a way to create a link that would open the embedded popup just like it opens when you click on it?

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

https://www.whitepaper.com.mx/30day

and you can use a link to your portal page

https://www.whitepaper.com.mx/#/portal/subscribe

2 Likes

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

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="https://unpkg.com/@tryghost/portal@latest/umd/portal.min.js" 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>
</form>

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>


<style>
form .feedback {
	display: none;
}

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

form.success .feedback {
	display: unset;
}
</style>

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.

2 Likes

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 *.ghost.io 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="https://unpkg.com/@tryghost/portal@latest/umd/portal.min.js" 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.