# Embeddable signup forms

**URL:** <https://forum.ghost.org/t/embeddable-signup-forms/48059>\
**Category:** Using Ghost\
**Created:** [June 11, 2024, 8:32pm UTC](https://forum.ghost.org/t/embeddable-signup-forms/48059 "2024-06-11T20:32:41Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ziggy](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/ziggy/32/30814_2.png) [@ziggy](https://forum.ghost.org/u/ziggy)\
**Post date:** [June 11, 2024, 8:32pm UTC](https://forum.ghost.org/t/embeddable-signup-forms/48059/1 "2024-06-11T20:32:41Z")

</div>

Hi There, I was searching on how to translate the embeddable signup forms. The button and the placeholder are in english but I need dutch. Also how to theme the input and button? The input and the button are to big so how can I resize it?

Kind regards,  
Ziggy

---

<div class="post-metadata">

**Author:** ![Ravn](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/ravn/32/20885_2.png) [@Ravn](https://forum.ghost.org/u/Ravn)\
**Post date:** [June 12, 2024, 2:12pm UTC](https://forum.ghost.org/t/embeddable-signup-forms/48059/2 "2024-06-12T14:12:00Z")

</div>

I am just solving embeddable signup forms styling on client’s landing page.  
It is rendering content of form in iframe so classic CSS can’t be used.  
I was able to restyle it using Javascript. Very ugly solution but it works.

 ![Screenshot 2024-06-12 at 16.11.17](https://us1.discourse-cdn.com/flex015/uploads/ghost2/original/3X/0/1/01867c533c9d62e4d2b17989de6217314590cf89.png)

---

<div class="post-metadata">

**Author:** ![ziggy](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/ziggy/32/30814_2.png) [@ziggy](https://forum.ghost.org/u/ziggy)\
**Post date:** [June 13, 2024, 8:52am UTC](https://forum.ghost.org/t/embeddable-signup-forms/48059/3 "2024-06-13T08:52:09Z")

</div>

Thanks Ravn, Ok nice that you found a workaround for styling. Do you have an example how you did this?

---

<div class="post-metadata">

**Author:** ![ziggy](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/ziggy/32/30814_2.png) [@ziggy](https://forum.ghost.org/u/ziggy)\
**Post date:** [June 13, 2024, 12:53pm UTC](https://forum.ghost.org/t/embeddable-signup-forms/48059/4 "2024-06-13T12:53:55Z")

</div>

How about the translation of this button and placeholder? Any help would be very appreciated :-)

---

<div class="post-metadata">

**Author:** ![Raki](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/raki/32/40808_2.png) [@Raki](https://forum.ghost.org/u/Raki)\
**Post date:** [June 20, 2024, 8:25am UTC](https://forum.ghost.org/t/embeddable-signup-forms/48059/6 "2024-06-20T08:25:23Z")

</div>

> [@Raki](#):
>
> This is possible, two ways:
> 
> - The Hard way: edit theme as shown in the [official guide](https://ghost.org/docs/themes/helpers/translate/)
> - Easy(dirty) way: change through code injection, but this requires inspecting your page code(I can’t tell which theme you are using)

This is possible, two ways:

- The Hard way: edit theme as shown in the [official guide](https://ghost.org/docs/themes/helpers/translate/)
- Easy(dirty) way: change through code injection, but this requires inspecting your page code(I can’t tell which theme you are using)

---

<div class="post-metadata">

**Author:** ![Ravn](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/ravn/32/20885_2.png) [@Ravn](https://forum.ghost.org/u/Ravn)\
**Post date:** [June 28, 2024, 11:35am UTC](https://forum.ghost.org/t/embeddable-signup-forms/48059/7 "2024-06-28T11:35:52Z")

</div>

Hi Ziggy,

I am sorry for the very late reply. I had to accommodate the code a little bit for the Safari browser. I have to warn you, it is a really horrible solution, but I assume there is no other way around it. Basically, the HTML nodes in the iframe are not present at the time the iframe is injected into the page. So, when we traverse the iframe HTML nodes, we have to check the presence of each node several times.

Code:

```auto
<div id="iframe_wrapper" style="min-height: 58px; max-width: 440px;width: 100%;position: absolute; left: 50%; top:50%; transform: translate(-50%, -50%);">
  <script src="https://cdn.jsdelivr.net/ghost/signup-form@~0.1/umd/signup-form.min.js" data-label-1="workspace-made-easy" data-button-color="#E6007C" data-button-text-color="#FFFFFF" data-site="https://your-ghost-website.com/" defer></script>
</div>

<script>

const style_signup_form = async(iframe) => {
  let children_check = 0;
  let content_document = null;
  let counter = 0;
  do{
    content_document = iframe.contentDocument;
    children_check = content_document.all.length;  
    await new Promise(resolve => setTimeout(resolve, 50));
    counter++;
  }while(children_check < 5 || counter > 10000)

  
  for(let item of content_document.all){
    if(item.tagName == 'BODY'){
      let form_ = undefined;
      let count = 0;
      do {
        console.log(item.chidren)
        count++;
        if(item.children[0]){
          form_ = item.children[0].lastChild ?? undefined;
        }              
        await new Promise(resolve => setTimeout(resolve, 50));
      }
      while (form_ == undefined || count > 10000); 
      //console.log('[form] -> ', form_);
      form_.style.borderRadius = '2px';
      form_.style.boxShadow = '0px 4px 18px 0px rgba(0,0,0,0.12)';
      form_.style.fontWeight = '300';
      form_.style.padding = '0px';
      let form_button = form_.querySelector('button');
      form_button.style.borderRadius = '2px';
      form_button.style.height = '3.9375rem';
      form_button.style.paddingLeft = '2.375rem';
      form_button.style.paddingRight = '2.375rem';
    }
  }
}
const catch_iframe = (node) => {  
  
  const iframe = node.querySelector('iframe');
  const observer_2 = new MutationObserver((mutationsList, observer) => {
          for (let mutation of mutationsList) {                
            if (mutation.type === 'childList') {
              mutation.addedNodes.forEach(node => {
                if(node.tagName == 'IFRAME'){
                  console.log('Iframe added:', node);
                  style_signup_form(node);
                }                
              });
           }
          }
  });
  observer_2.observe(node, {childList: true, subtree:false});

}
      
const iframe_wrapper = document.getElementById('iframe_wrapper');
const observer = new MutationObserver((mutationsList, observer) => {
      for (let mutation of mutationsList) {                
        if (mutation.type === 'childList') {
          mutation.addedNodes.forEach(node => {
            console.log('Added div node:', node);
            catch_iframe(node);
          });
       }
      }
});
observer.observe(iframe_wrapper, {childList: true, subtree:false});
        
     
</script>

```
