Skip to content

Instantly share code, notes, and snippets.

@cjimmy
Last active August 8, 2022 01:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cjimmy/4d12a8c7fcf1594015a426f14642e9e4 to your computer and use it in GitHub Desktop.
Save cjimmy/4d12a8c7fcf1594015a426f14642e9e4 to your computer and use it in GitHub Desktop.
amp-animation in React or jsx

Problem

AMP Animation requires a JSON which requires us to specially format it for React.

If you follow this AMP Scroll To Top Example, and paste this section into the render method

// !! This won't work if you paste it into React
<amp-animation id="showAnim" layout="nodisplay">
  <script type="application/json">
    {
      "duration": "200ms",
      "fill": "both",
      "iterations": "1",
      "direction": "alternate",
      "animations": [{
        "selector": "#scrollToTopButton",
        "keyframes": [{
          "opacity": "1",
          "visibility": "visible"
        }]
      }]
    }
  </script>
</amp-animation>

... you'll end up with an error like Unexpected token, expected "}", again, because react thinks you're about to enter more jsx.

Solution

In order to fix this, (and similar to the problem with ld+json), you need to escape the JSON and make it a string literal with {``}

// Note this happens inside the <script> tag itself
<amp-animation id="showAnim" layout="nodisplay">
  <script type="application/json" dangerouslySetInnerHTML={{__html: JSON.stringify(
    {
      "duration": "200ms",
      "fill": "both",
      "iterations": "1",
      "direction": "alternate",
      "animations": [{
        "selector": "#scrollToTopButton",
        "keyframes": [{
          "opacity": "1",
          "visibility": "visible"
        }]
      }]
    }
  )
  }}>
  </script>
</amp-animation>

Because we need to use JSON.stringify anyways, you can break it out into its own object.

//-- INCOMPLETE EXAMPLE, just showing the important parts.

const hideAnim = 
  {
    duration: "200ms",
    fill: "both",
    iterations: "1",
    direction: "alternate",
    animations: [{
      selector: "#scrollToTopButton",
      keyframes: [{
        opacity: "1",
        visibility: "visible"
      }]
    }]
  }
  

return (
  <amp-animation id="hideAnim" layout="nodisplay">
    <script type="application/json" dangerouslySetInnerHTML={{__html: JSON.stringify(hideAnim)}}>
    </script>
  </amp-animation>
)

Seems like a trivial problem, but I didn't see it documented anywhere. So writing this for the benefit of those searching for an answer.

@elianasoledadescudero2120

Thank you very much!!! Really useful!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment