2

I am trying to implement a form solution from formstack into my React/Gatsby website. To do so, I need to use postscribe to inject an external script. I've followed a couple other people and I have a working version locally with the following code:

import postscribe from postscribe

...

useEffect(() => {
    if (advRef) {
      if (window !== undefined) {
        postscribe(
          advRef.current,
          "<script src=...myformurl...><\/script>",
        )
      }
    }
  }, [advRef])

...
        
<div id="adv" ref={advRef}></div>

However, this does not work in production and it throws a ReferenceError: window is not defined error. I have run into this before and as you can see I tried the if window is defined block, but that doesn't seem to help.

I saw in another question here that this has to do with how postscribe is imported. But I can't seem to get the solution here to work either.

sergdenisov
  • 8,327
  • 9
  • 48
  • 63
yankeedoodle
  • 353
  • 2
  • 11

2 Answers2

1

I needed a way to load the script using a script tag rather downloading the node package. The answer to this post goes into it a bit, but as far as I understand it has something to do with when postscribe tries to make changes to the page. Idk why this way works but I did the following in my Gatsby project.

  1. install gatsby-plugin-load-script
  2. Add the following to gatsby config
{
    resolve: 'gatsby-plugin-load-script',
      options: {
        src: 'https://cdnjs.cloudflare.com/ajax/libs/postscribe/2.0.8/postscribe.min.js'
     },
},
  1. create tsx component for forms that looks like the following
import React, { useEffect, useRef } from 'react';
// import postscribe from 'postscribe';
declare let postscribe: any;

type Props = {
  externalScript: string,
  id: string
}

const Formstack: React.FC<Props> = ({externalScript, id}) => {
  const formRef = useRef(null)

  useEffect(() => {
    if (formRef) {
      if (typeof window !== "undefined") {
        postscribe(
          formRef.current,
          `<script src=${externalScript}><\/script>`,
        )
      }
    }
  }, [formRef])
  return (
    <div>
      <div>above the form</div>
      <div id={id} ref={formRef}></div>
      <div>below the form</div>
    </div>
  )
}

export default Formstack;

yankeedoodle
  • 353
  • 2
  • 11
  • this does seem to cause some odd errors though. The form works only on the users first visit of the page. But even if they don't submit, and refresh the page, the form breaks – yankeedoodle Jul 05 '22 at 20:53
  • Could you create a reproducible example on https://codesandbox.io? Maybe I could help. – sergdenisov Jul 06 '22 at 12:20
0

Try to change your checking from window !== undefined to typeof window !== "undefined":

import postscribe from postscribe

...

useEffect(() => {
  if (advRef) {
    if (typeof window !== "undefined") {
      postscribe(
        advRef.current,
        "<script src=...myformurl...><\/script>",
      )
    }
  }
}, [advRef])


...

<div id="adv" ref={advRef}></div>
sergdenisov
  • 8,327
  • 9
  • 48
  • 63