p5.jsastrojs

I'm struggling to add a p5.js sketch to my Astro website


I'm developing my personal website with Astro. Parts of my website require running p5.js sketches. I have added <script> tags for both p5.js and my sketch, but when I run the page, it's as if p5.js isn't running. There is no canvas added to the DOM, nor are there any errors in the console.

I have added a console.log to my sketch, so I can confirm that my sketch code is running.

If I download p5.js locally, place it in the /Public folder and import it with <script is:inline src="/p5.js"></script> then I can verify that it also does run with a console.log. Alternatively, if I import p5.js from the CDN, then I can see from the network logs that the script is being downloaded without issue.

I'm not sure how else to troubleshoot this problem. Any help would be appreciated!

Minimal Example

Here's an Astro page (put in the pages folder) which illustrates my problem:

<!DOCTYPE html>
<html lang="en" dir="ltr">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>min p5js with astro example</title>

        <!-- Import p5.js. First way is directly from the downloaded source in /public. SEcond way is from the CDN -->
        <!-- <script is:inline src="/p5.js"></script> -->
        <script is:inline src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>


        <script>
            console.log("Running script...")
            function setup() {
                createCanvas(400, 400);
                background(0);
            }

            function draw() {
                fill(255);
                ellipse(mouseX, mouseY, 80, 80);
            }
        </script>
    </head>
    <body>
    </body>
</html>

So far I've tried


Solution

  • You either do the "modern" way: npm install p5 and then putting something like this in tag without is:inline:

    <script>
    import p5 from 'p5'
    new p5(mySketch, document.getElementById('sketch'))
    </script>
    

    The above treats the code as a module (meaning local variables are not assigned to window, etc.) and runs it through Astro's bundler and minimizer (using vite under the hood).

    Alternatively, you have to use is:inline in all the script tags. This prevents Astro from processing the script:

    <script is:inline src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
    <script is:inline>
      function setup() {
        createCanvas(400, 400);
      }
      function draw() {
        fill(255);
        ellipse(mouseX, mouseY, 80, 80);
      }
    </script>
    

    Which is assigning the two functions to window.setup and window.draw respectively.