# More than one sketch in same HTML page

**URL:** <https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447>\
**Category:** Coding Questions\
**Created:** [December 10, 2024, 12:43pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447 "2024-12-10T12:43:42Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![edufissure](https://avatars.discourse-cdn.com/v4/letter/e/e56c9b/32.png) [@edufissure](https://discourse.processing.org/u/edufissure)\
**Post date:** [December 10, 2024, 12:43pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/1 "2024-12-10T12:43:42Z")

</div>

My index.html ( relevant code):

```auto

  <!--Utilitzem la llibreria p5-->
    <script type="module" src="/js/libraries/p5.min.js"></script>
    <!--Carreguem moduls-->

    <!--Carreguem sketch-->
    <script type="module" src="/js/sketch.js"></script>
    <script type="module" src="/js/secondsketch.js"></script>
<p>Hello world! This is HTML5 Boilerplate.</p>
<div id="sketch-holder"></div>
<p>Pagina hecha con HTML5</p>
<div id="second-sketch-holder"></div>
<img src="/img/imghtml5.jpg" alt="Pacman" width="200" height="200">

```

secondsketch.js

```auto

function setup() {
  // Creates a canvas 600 pixels wide
  // and 400 pixels high.
  createCanvas(400, 200).parent("#second-sketch-holder");
}

function draw() {
    textSize(100);
    text("Valor de a: " + globalThis.a, 10, 10);
}

globalThis.setup = setup;
globalThis.draw = draw;

```

sketch.js

```auto
function setup() {
  // Creates a canvas 600 pixels wide
  // and 400 pixels high.
  createCanvas(600, 400).parent("#sketch-holder");
}

function draw() {
  // sky blue background
  background(135, 206, 235);
  globalThis.a = 5;
  // sun in top right
  fill("yellow"); // yellow

  stroke("orange"); // orange outline

  strokeWeight(20); // large outline

  circle(550, 50, 100);
}

globalThis.setup = setup;
globalThis.draw = draw;

```

The problem suppose is the name of setup and draw functions that are the same, and as you can see im trying to share a “global” variable **a** to transport data from one canvas o sketch to the other…  
The idea is one sketch/sketch for the game and the other canvas to act as scoreboard with time and points for example

Thanks

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [December 10, 2024, 12:57pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/2 "2024-12-10T12:57:41Z")

</div>

> [@edufissure](#):
>
> `<script type="module" src="/js/libraries/p5.min.js"></script>`

“p5.min.js” isn’t a ECMA Script Module (ESM) file, so `type="module"` is unneeded, even though in this particular case, it doesn’t have any bad consequences.

Also, starting the path w/ “/” here it unneeded.

For better performance for regular JS scripts, use `defer`.  
Or even `async` if there’s no library relying on “p5.js”:  
`<script async src="js/libraries/p5.min.js"></script>`

Optionally, you can grab “p5.js” via a CDN:  
`<script async src="//cdn.JsDelivr.net/npm/p5"></script>`

> [@edufissure](#):
>
> ```auto
> <script type="module" src="/js/sketch.js"></script>
> <script type="module" src="/js/secondsketch.js"></script>
> 
> ```

Neither of your 2 sketches are module files.  
Again, you don’t need `type="module"` and you can start their path w/o a leading “/”:

```auto
<script async src="js/sketch.js"></script>
<script async src="js/secondsketch.js"></script>

```

And given they’re not being loaded as modules (non-ESM) anymore, you can delete these lines:

```auto
globalThis.setup = setup;
globalThis.draw = draw;

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [December 10, 2024, 1:41pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/3 "2024-12-10T13:41:37Z")

</div>

> [@edufissure](#):
>
> The idea is one sketch for the game and the other canvas to act as scoreboard…

For each [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe), including the root frame, we can have at most only 1 p5.js sketch using the “global mode”.

Either you create a separate HTML file for 1 of your 2 sketches, so it can be loaded in a separate `<iframe>` or…

You convert 1 of them to use p5.js “instance mode”:

> **[Multiple Canvases](https://p5js.org/examples/advanced-canvas-rendering-multiple-canvases/)**
>
> Use Instance Mode to put multiple canvases on the page.

Let’s say you keep your sketch “sketch.js” (the biggest 1) in “global mode”:

```auto
"use strict";

var bg, a = 5; // 'a' is a global variable b/c it's' declared w/ `var` keyword

function setup() { // setup is a global variable b/c it's declared w/ `function` 
  createCanvas(600, 400).parent("sketch-holder");
  fill("yellow").stroke("orange").strokeWeight(20);
  bg = color(135, 206, 235); // sky blue
}

function draw() { // draw is a global variable b/c it's declared w/ `function`
  background(bg).circle(550, 50, 100);
}

```

So now you need to convert your sketch “secondsketch.js” (the smallest 1) to “instance mode”:

```auto
"use strict";

new p5(p => {

  p.setup = function () {
    this.createCanvas(400, 200).parent("second-sketch-holder");
    this.textSize(100);
  };

  p.draw = function () {
    this.text("Valor de a: " + a, 10, 10); // var 'a' was defined in "sketch.js"
  };

});

```

And their HTML file:

```auto
<!-- <script async src="js/libraries/p5.min.js"></script> -->
<script async src="//cdn.JsDelivr.net/npm/p5"></script>

<script async src="js/sketch.js"></script>
<script defer src="js/secondsketch.js"></script>

<p>Hello world! This is HTML5 Boilerplate.</p>
<div id="sketch-holder"></div>

<p>Pagina hecha con HTML5</p>
<div id="second-sketch-holder"></div>

<img src="img/imghtml5.jpg" alt="Pacman" width="200" height="200">

```

---

<div class="post-metadata">

**Author:** ![edufissure](https://avatars.discourse-cdn.com/v4/letter/e/e56c9b/32.png) [@edufissure](https://discourse.processing.org/u/edufissure)\
**Post date:** [December 10, 2024, 2:44pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/4 "2024-12-10T14:44:15Z")

</div>

And can be both of them in instance mode ? i usually make the code and finally when all is working i transform from global to instance mode…

About module:

- In my tests it works with and without type=“module”
- Also works with the only put defer in seconsketch…this thing i dont understand because in theory secondsketch is loaded after sketch, so would not need any extra parameter like defer
- Global.this = draw; is not necessary in sketch.js ¿?¿

So i make some extra tests…i need type=“module” to use p5.js in vercel

I use vite in local, and then deploy to vercel…

secondsketch.js

```auto
"use strict";

new p5(p => {

    p.setup = function () {
        this.createCanvas(400, 200).parent("#second-sketch-holder");
        this.textSize(22);
    };

    p.draw = function () {
        this.background(135, 206, 235);
        this.fill('yellow');
        console.log("variable a is: ", a);
        this.text(`${a}`, 10, 50); // var 'a' was defined in "sketch.js"
    };

});

```

sketch.js

```auto
let a=5;

function setup() {
  // Creates a canvas 600 pixels wide
  // and 400 pixels high.
  createCanvas(600, 400).parent("#sketch-holder");
  a++;
}

function draw() {
  // sky blue background
  background(135, 206, 235);
  // sun in top right
  fill("yellow"); // yellow

  stroke("orange"); // orange outline

  strokeWeight(20); // large outline

  circle(550, 50, 100);
}

globalThis.setup = setup;
globalThis.draw = draw;

```

index.html

```auto
    <!--Carreguem sketch-->
    <script type="module" src="/js/sketch.js"></script>
    <script type="module" src="/js/secondsketch.js"></script>

</head>
<body>
<p>Hello world! This is HTML5 Boilerplate.</p>
<div id="sketch-holder"></div>
<p>Pagina hecha con HTML5</p>
<div id="second-sketch-holder"></div>
<img src="/img/imghtml5.jpg" alt="Pacman" width="200" height="200">

</body>

```

It show the first one but not the second one, with the variable **a**  
Uncaught reference error a is not defined

 ![imagen](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/c/c/cc2be9868e1fa2120eacc9ab6ef0fe44e53934f7.png)

I get it to work local with vite, but didnt in vercel… so i had to add the type module…but dont know how to get back…i made lots of tests with defers and asyncs…and didnt get with it…

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [December 10, 2024, 5:48pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/5 "2024-12-10T17:48:12Z")

</div>

> [@edufissure](#):
>
> i usually make the code and finally when all is working i transform from global to instance mode…

I used to do that because the global mode involved less typing but once the sketch got big this became a pain in the butt. 😄

Now I do most of my coding in instance mode because although it is more work initially it makes it easy to have multiple canvas sketches.

So here is a basic example of a webpage that has 2 ‘sketches’ each with their own canvas.

**html file**

```html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Multi-canvas example</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.8.0/p5.min.js"></script>

    <script src="multicanvas.js" type="text/javascript"></script>

</head>

<body>
    <p>Main display canvas</p>
    <div id='main_canvas'></div>
    <br><br>
    <p>Sub display canvas</p>
    <div id='sub_canvas'></div>
</body>

</html>

```

**js file**

```js
/*
File: multicanvas.js
Keys:
'm' sends a message from MAIN canvas to SUB canvas
's' sends a message from SUB canvas to MAIN canvas
*/

let main_display = function (p) {

    let string = '';

    p.setup = function () {
        p.createCanvas(400, 300);
        p.cursor(p.CROSS);
        p.fill('darkgreen');
        p.textSize(24);
    }

    p.draw = function () {
        p.background('lightgreen');
        p.text(string, 40, 40);
    }

    p.sendMessage = function (message) {
        sub.setMessage(`Message from MAIN canvas \n"${message}"`);
    }

    p.setMessage = function (message) {
        string = message;
    }

    p.keyTyped = function () {
        if (p.key == 'm')
            main.sendMessage('Quark finds a way! ')
    }
}

let sub_display = function (p) {

    let string = '';

    p.setup = function () {
        p.createCanvas(300, 200);
        p.cursor(p.HAND);
        p.fill('darkblue');
        p.textSize(20);
    }

    p.draw = function () {
        p.background('lightblue');
        p.text(string, 20, 40);
    }

    p.sendMessage = function (message) {
        main.setMessage(`Message from SUB canvas \n"${message}"`);
    }

    p.setMessage = function (message) {
        string = message;
    }

    p.keyTyped = function () {
        if (p.key == 's')
            p.sendMessage('Quark seeks the truth')
    }
}

let main = new p5(main_display, 'main_canvas');

let sub = new p5(sub_display, 'sub_canvas');

```

There are other issues you need to take into account - for instance all key and mouse events on the web page will be processed by both sketches but this example might help get you started.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [December 10, 2024, 11:26pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/6 "2024-12-10T23:26:25Z")

</div>

> [@edufissure](#):
>
> And can both of them be in “instance mode”?

Absolutely! I was just reminding you that up to 1 of the sketches can be kept as “global mode”.

> [@edufissure](#):
>
> Also works if only put `defer` in “seconsketch.js”… this thing I don’t understand because in theory “secondsketch.js” is loaded after “sketch.js”, so would not need any extra parameter like `defer`.

- If we have `async` for loading “p5.js” library, the browser will run that file immediately when it’s done loading it.
- That will make the variable p5 globally available.
- However, “secondsketch.js” has this line: `new p5(p => {`
- If p5 happens to not exist yet at the moment it’s executed, that code will crash!
- That’s why I’ve used `defer` in place of `async` to load “secondsketch.js”; so its execution will be postponed much later; which by then p5 already had enough time to be made globally available.

> [@edufissure](#):
>
> `globalThis = draw;` is not necessary in “sketch.js”¿?¿

If we don’t use `type=module` to load a file; and make sure we declare variables using either `var` or `function` keywords, that will automatically place those variables in `globalThis`.

> [@edufissure](#):
>
> So I’ve made some extra tests… I need `type="module"` to use “p5.js” in Vercel.

Even though the “p5.js” is just a regular JS script, the way it is coded, it doesn’t really matter if we force it to be loaded as an ESM module if we prefer or need it that way.

However, for those 2 “sketch” files, you’ll have to make changes to them depending whether you’ll load them as regular JS scripts or as ESM module files.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [December 10, 2024, 11:44pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/7 "2024-12-10T23:44:01Z")

</div>

> [@edufissure](#):
>
> It show the first one but not the second one, with the variable **a**  
> Uncaught reference error _a_ is not defined.

- You’ve used keyword `let` instead of `var` to declare it: `let a = 5;`
- Only variables declared w/ keywords `var` & `function` can also automatically place them in `globalThis`.
- The others: `let`, `const`, `class`, `import` don’t have such feature!
- Also, if a file is loaded as an ESM module, no matter which keyword we use, no variables will automatically be placed in `globalThis` as well!
- For module files, we have to explicitly use `globalThis`.
- Remember that execution behavior changes depending on how a file has been loaded, as a regular JS script, ESM or CommonJS.

> **[JavaScript modules - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#other_differences_between_modules_and_classic_scripts)**
>
> This guide gives you all you need to get started with JavaScript module syntax.

---

<div class="post-metadata">

**Author:** ![edufissure](https://avatars.discourse-cdn.com/v4/letter/e/e56c9b/32.png) [@edufissure](https://discourse.processing.org/u/edufissure)\
**Post date:** [December 11, 2024, 11:09am UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/8 "2024-12-11T11:09:33Z")

</div>

> [@GoToLoop](#):
>
> ```auto
> "use strict";
> 
> new p5(p => {
> 
> p.setup = function () {
> this.createCanvas(400, 200).parent("second-sketch-holder");
> this.textSize(100);
> };
> 
> p.draw = function () {
> this.text("Valor de a: " + a, 10, 10); // var 'a' was defined in "sketch.js"
> };
> 
> });
> 
> ```

Thanks for your help,im very grateful and so my students…

1 - With your code let or var is not the problem. You can safely put let a=5: and works…as i told you at least in JS var is almost deprecated, dont know if p5.js still uses it as you said

2 - For now, im trying to get help in Vercel i need to put type=“module”, and surely when the project gets bigger id need to use imports/exports at least in sketch.js wheres is supposed to be the pacman game. So i need how to share variable a using modules…

3 - Is cleaner or do you recommend use instance mode instead of global mode ?

---

<div class="post-metadata">

**Author:** ![edufissure](https://avatars.discourse-cdn.com/v4/letter/e/e56c9b/32.png) [@edufissure](https://discourse.processing.org/u/edufissure)\
**Post date:** [December 11, 2024, 3:29pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/9 "2024-12-11T15:29:18Z")

</div>

This is my “final code”:

index.html

```html
<!doctype html>
<html class="no-js" lang="">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title></title>
  <link rel="stylesheet" href="css/style.css">
  <meta name="description" content="">

  <meta property="og:title" content="">
  <meta property="og:type" content="">
  <meta property="og:url" content="">
  <meta property="og:image" content="">
  <meta property="og:image:alt" content="">

  <link rel="icon" href="/favicon.ico" sizes="any">
  <link rel="icon" href="/icon.svg" type="image/svg+xml">
  <link rel="apple-touch-icon" href="icon.png">

  <link rel="manifest" href="site.webmanifest">
  <meta name="theme-color" content="#fafafa">
    <!--
    Si usamos async para cargar la biblioteca "p5.js", el navegador ejecutará ese archivo inmediatamente cuando termine de cargarlo.
 That will make the variable p5 globally available. -->
    <script defer type="module" src="js/libraries/p5.min.js"></script>
    <script defer type="module" src="js/sketch.mjs"></script>
    <script defer type="module" src="js/secondsketch.mjs"></script>

</head>

<body>

  <!-- Add your site or application content here -->
  <p>Hello world! This is HTML5 Boilerplate.</p>
  <div id="first-sketch-holder"></div>
   <p>Hello world! This is HTML5 Boilerplate.</p>
  <div id="second-sketch-holder"></div>

</body>

</html>

```

sketch.mjs

```Javascript
import {Rectangle} from "./classes/Rectangle.mjs";

globalThis.a=5;
let b=8;

const s = ( sketch ) => {

    let myrect = new Rectangle(10, 20);

    sketch.setup = () => {
        // Creates a canvas 600 pixels wide
        // and 400 pixels high.
        sketch.createCanvas(600, 400);
        globalThis.a++;
        b++;
        console.log(myrect.area);
    }

    sketch.draw = () => {
        sketch.background(135, 206, 235);
        // sun in top right
        sketch.fill("yellow"); // yellow

        sketch.stroke("orange"); // orange outline

        sketch.strokeWeight(20); // large outline

        sketch.circle(550, 50, 100);
    };
    sketch.keyPressed = () => {

        if (sketch.keyCode === sketch.RIGHT_ARROW) {
            b++;
            }
        else if (sketch.keyCode === sketch.LEFT_ARROW) {
            b--;
            }
            }//ends function keyPressed
};

let myp5 = new p5(s, document.getElementById('first-sketch-holder'));

export {b}; // Exporting 'b' to be used in "secondsketch.mjs"

```

secondsketch.mjs

```auto
"use strict";
import {b} from "./sketch.mjs";

const s2 = (secondsketch) => {

    secondsketch.setup = () => {
        secondsketch.createCanvas(400, 200);
        secondsketch.textSize(12);
    };

    secondsketch.draw = ()=> {
        secondsketch.background(220);
        secondsketch.text("Valor de a: " + globalThis.a, 20, 50); // var 'a' was defined in "sketch.mjs"
        secondsketch.text("Valor de b: " + b, 20, 80); // var 'a' was defined in "sketch.mjs"

    };

};

let mysecondp5 = new p5(s2, document.getElementById('second-sketch-holder'));

```

Rectangle.mjs

```auto
export class Rectangle {
    constructor(alto, ancho) {
        this.alto = alto;
        this.ancho = ancho;
    }
    // Getter
    get area() {
        return this.calcArea();
    }
    // Métodos
    calcArea() {
        return this.alto * this.ancho;
    }
}

```

1 - As told you seems that let or var is not the problem…but is a little detail using var or let…

2 - if put async it doesnt work:

```auto
   <script async type="module" src="js/libraries/p5.min.js"></script>
    <script defer type="module" src="js/sketch.mjs"></script>
    <script defer type="module" src="js/secondsketch.mjs"></script>

```

Which i dont understand…as p5.min.js doesnt rely or depend on other libraries or files or modules…

```auto
Uncaught ReferenceError: p5 is not defined

<anonymous> http://localhost:63342/MeuPacman/js/sketch.mjs:41

2 [sketch.mjs:41:12](http://localhost:63342/MeuPacman/js/sketch.mjs)

```

3 - This also works: all modules to async…i dont understand because seconsketch depends of variable b in first sketch…

```auto
   <script async type="module" src="js/libraries/p5.min.js"></script>
    <script async type="module" src="js/sketch.mjs"></script>
    <script async type="module" src="js/secondsketch.mjs"></script>

```

4- Without anything it works also…

```auto
  <script type="module" src="js/libraries/p5.min.js"></script>
    <script type="module" src="js/sketch.mjs"></script>
    <script type="module" src="js/secondsketch.mjs"></script>

```

5 -This also works:

```auto
    <script src="js/libraries/p5.min.js"></script>
    <script src="js/sketch.mjs"></script>
    <script type="module" src="js/secondsketch.mjs"></script>

```

So do you “like” this code ? is more modern and flexible…without using globalThis and using import/export modules in ESM.

Also if i add which it should not hurt after the other scripts…it always fails… I dont know why…

` <script type="module" src="js/classes/Rectangle.mjs"></script>`

By now id try to test this in Vite, and then in Vercel.

BTW. Is recommended use strict mode? or coding with Eslint is enough ?

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [December 12, 2024, 3:55am UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/10 "2024-12-12T03:55:54Z")

</div>

> [@edufissure](#):
>
> 1 - As told it seems that `let` or `var` are not the problem…

There are some particular behaviors for the keyword we choose to declare a variable in JS with. But for most of cases, it won’t matter. But watch out for the rare cases where it actual matters!

> [@edufissure](#):
>
> 2 - if put `async` it doesn’t work:

AFAIK, both `<script>` attributes `async` & `defer` are ignored when using `type=module`!  
Files loaded via `type=module` are automatically deferred by default btW.

> [@edufissure](#):
>
> So do you like this code? It’s more modern and flexible… without using `globalThis` and using `import/export` modules in ESM.

I’ve come up w/ a better idea on how to “share” variables _a_ & _b_ between “sketch.mjs” & “secondsketch.mjs”.

Rather than using `globalThis` or `export/import`, we can instead add them both as additional properties of the p5.js sketch instance:

## “sketch.mjs”:

```js
// Importing class Rectangle from file "Rectangle.mjs" in subfolder "classes":
import Rectangle from "../classes/Rectangle.mjs";

// Exporting sketch() callback so it can be accessed by "secondsketch.mjs":
export default function sketch(p) { // param "p" is the the newly created sketch
  // Make this p5.js sketch instance "p" see its callback methods:
  p.setup = setup;
  p.draw = draw;
  p.keyPressed = keyPressed;

  p.a = 5; // p5 instance property "a" added
  p.b = 8; // p5 instance property "b" added

  p.myrect = new Rectangle(10, 20); // p5 instance property "myrect" added
}

```

In the exported callback **sketch()** above, besides adding the regular **setup()**, **draw()** and **keyPressed()** callbacks to the newly instantiated p5.js sketch _p_, it also adds 3 more properties: _a_, _b_ and _myrect_; so any other file that imports file “sketch.mjs” and instantiates its **sketch()** will also have access to those 3 extra properties:

## “secondsketch.mjs”:

```js
// Importing sketch() callback from file "sketch.mjs" as firstSketch():
import firstSketch from "./sketch.mjs";

// Exporting sketch() callback so it can be accessed by "index.mjs":
export default function sketch(p) { // param "p" is the the newly created sketch
  // Make this p5.js sketch instance "p" see its callback methods:
  p.setup = setup;
  p.draw = draw;

  // Instantiates firstSketch() and places it in <div> id="first-sketch-holder":
  p.firstSketch = new p5(firstSketch, "first-sketch-holder");

  // "secondsketch.mjs" will be known by "sketch.mjs" as property "panel":
  p.firstSketch.panel = p;
}

```

As you can spot from the code above, “secondsketch.mjs”'s own callback **sketch()** is instantiating “sketch.mjs”'s **sketch()** and keeping that as its property “firstSketch”.

This way, “secondsketch.mjs” can access “a”, “b”, “myrect” and any other p5.js props from it via its own “firstSketch” property:

## “draw()”:

```js
  // Unpack instance properties "a" & "b" from property "firstSketch":
  const { a, b } = this.firstSketch;

  // Instance property "a" from "sketch.mjs" p5.js sketch:
  this.text("Valor de a: " + a, 20, 50);

  // Instance property "b" from "sketch.mjs" p5.js sketch:
  this.text("Valor de b: " + b, 20, 80);

```

I’ve also created a new file called “index.mjs” which will act as an entry point:  
`<script type="module" src="index.mjs"></script>`

## “index.mjs”:

```js
// Importing sketch() callback from file "secondsketch.mjs" in subfolder "js":
import sketch from "./js/secondsketch.mjs";

// Instantiates sketch() and places it in <div> id="second-sketch-holder":
new p5(sketch, "second-sketch-holder");

```

The order is: “index.html” loads “index.mjs”, which in turn will import “js/secondsketch.mjs”; and the latter will import “js/sketch.mjs”, which will then import “classes/Rectangle.mjs”:

1. 127.0.0.1 - - [12/Dec/2024] “GET /index.mjs HTTP/1.1” 200 -
2. 127.0.0.1 - - [12/Dec/2024] “GET /js/secondsketch.mjs HTTP/1.1” 200 -
3. 127.0.0.1 - - [12/Dec/2024] “GET /js/sketch.mjs HTTP/1.1” 200 -
4. 127.0.0.1 - - [12/Dec/2024] “GET /classes/Rectangle.mjs HTTP/1.1” 200 -
5. 127.0.0.1 - - [12/Dec/2024] “GET /favs/site.webmanifest HTTP/1.1” 200 -
6. 127.0.0.1 - - [12/Dec/2024] “GET /favs/favicon.svg HTTP/1.1” 200 -

The complete code is on my latest repo:

> **[GitHub - GoToLoop/ESM-Sun-Manifesto-Demo: Demos how to run 2 p5.js ".mjs" sketches where 1...](https://github.com/GoToLoop/ESM-Sun-Manifesto-Demo)**
>
> Demos how to run 2 p5.js ".mjs" sketches where 1 can access the other

And you can check it out running online here:

> **[ESM Sun Manifesto Demo](https://gotoloop.github.io/ESM-Sun-Manifesto-Demo/)**
>
> 2 p5.js '.mjs' sketches sharing properties

Feel free to ask about any part you may not understand.

---

<div class="post-metadata">

**Author:** ![edufissure](https://avatars.discourse-cdn.com/v4/letter/e/e56c9b/32.png) [@edufissure](https://discourse.processing.org/u/edufissure)\
**Post date:** [December 12, 2024, 7:51pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/11 "2024-12-12T19:51:48Z")

</div>

@GoToLoop Thanks for your help…

Do you know about Vercel + Vite…im going mad as code in Vite works fine but in Vercel i got an error:

```auto
Uncaught ReferenceError: p5 is not defined

```

??

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [December 12, 2024, 10:16pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/12 "2024-12-12T22:16:26Z")

</div>

> [@edufissure](#):
>
> Do you know about Vercel + Vite…

Neither! I had to ask a chatbot about them.  
It seems like Vercel is a hosting service w/ extra features.

> [@edufissure](#):
>
> `Uncaught ReferenceError: p5 is not defined`

B/c in the HTML file, “p5.js” library is run 1st:  
`<script defer src="//cdn.JsDelivr.net/npm/p5"></script>`

And only then “index.mjs” is run:  
`<script type="module" src="index.mjs"></script>`

Property p5 has to globally exist when [“index.mjs”](https://github.com/GoToLoop/ESM-Sun-Manifesto-Demo/blob/main/index.mjs) runs this line:  
`new p5(sketch, "second-sketch-holder");`

No idea how Vercel would be interfering w/ the “p5.js” execution order. 😕

Anyways, in my [latest version 1.0.2](https://github.com/GoToLoop/ESM-Sun-Manifesto-Demo/releases/latest), I’ve moved everything related on loading p5.js files to a separate HTML file “p5js.html”:

> <https://github.com/GoToLoop/ESM-Sun-Manifesto-Demo/blob/main/p5js.html>

Now, [“index.html”](https://github.com/GoToLoop/ESM-Sun-Manifesto-Demo/blob/main/index.html) main file loads [“p5js.html”](https://github.com/GoToLoop/ESM-Sun-Manifesto-Demo/blob/main/p5js.html) as an [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe):

> <https://github.com/GoToLoop/ESM-Sun-Manifesto-Demo/blob/v1.0.2/index.html#L27-L31>

Maybe moving all of the “p5.js” related stuff to a separate HTML file might help Vercel behave better? 🤷‍♂️

---

<div class="post-metadata">

**Author:** ![edufissure](https://avatars.discourse-cdn.com/v4/letter/e/e56c9b/32.png) [@edufissure](https://discourse.processing.org/u/edufissure)\
**Post date:** [December 14, 2024, 6:26pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/13 "2024-12-14T18:26:50Z")

</div>

Thanks…but in local with Vite works fine…  
I expect some help of the Vercel community…i keep you updated…

By the way how about p5.sound is deprecated or abandonware ? I readed something but i was paying my attention to this Vercel problem…i read about howler as "preferred· sound library…

Do you know anything ? Som light in the darkness ?

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [December 14, 2024, 6:35pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/14 "2024-12-14T18:35:44Z")

</div>

> [@edufissure](#):
>
> By the way how about p5.sound is deprecated or abandonware?

I’ve never used it; only for some tests. But its reference still exists:

> **[p5.sound Reference](https://p5js.org/reference/p5.sound/)**
>
> Extend p5.js with Web Audio functionality including audio input, playback, analysis and synthesis.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [December 14, 2024, 6:44pm UTC](https://discourse.processing.org/t/more-than-one-sketch-in-same-html-page/45447/15 "2024-12-14T18:44:36Z")

</div>

> [@edufissure](#):
>
> I expect some help of the Vercel community…

On my repo version, p5 is accessed twice:

> <https://github.com/GoToLoop/ESM-Sun-Manifesto-Demo/blob/main/index.mjs#L4-L5>

> <https://github.com/GoToLoop/ESM-Sun-Manifesto-Demo/blob/main/js/secondsketch.mjs#L10-L11>

And I make sure “p5.js” runs before “index.mjs”; so p5 exists before “index.mjs” runs `new p5`:

> <https://github.com/GoToLoop/ESM-Sun-Manifesto-Demo/blob/main/p5js.html#L8-L9>

Sorry, but I have no idea how Vercel would interfere w/ that loading order.

> [@edufissure](#):
>
> I expect some help from Vercel community… I’ll keep you updated…

> <https://github.com/processing/p5.js/issues/7424>
>
> \### Topic
> 
> Not showing p5,js sketches as Vercel gives an not defined error, in V…ite works fine.
> Also would like to go to myrpoject/docs and show the jsdoc documentation.
> 
> Load my project, and sketches are not shown…
> 
> \[vercel.com\] (https://vercel.com/login?next=%2Fejgutierrez74s-projects%2Fpacman2024windows)
> \[Dashboard\] (https://vercel.com/login?next=%2Fejgutierrez74s-projects%2Fpacman2024windows)
> 
> With vite works fine, but in vercel i got an error when i deploy to Vercel
> 
> \`\`\`
> Uncaught ReferenceError: p5 is not defined
> Nn https://pacman2024windows.vercel.app/assets/index-Df26wdtU.js:1776
> An https://pacman2024windows.vercel.app/assets/index-Df26wdtU.js:1
> \<anonymous\> https://pacman2024windows.vercel.app/assets/index-Df26wdtU.js:1776
> \`\`\`
> 
> As vite in local i want to access my index.html showing some p5.js sketches, and then if i go to myproject/docs show de index of documentation.
> 
> Structure of my project;
> 
> !\[imagen\](https://github.com/user-attachments/assets/ea8cf2f8-3e30-4054-809a-f9c09d849903)
> 
> This is the caling of scripts in index.html in root project:
> \`\`\`
> 
> \<script type="module" src="js/libraries/p5.min.js"\>\</script\>
>     
> 
>     
> \<script type="module" src="/js/sketch.mjs"\>\</script\>
> \<script type="module" src="/js/secondsketch.mjs"\>\</script\>
> \`\`\`
> 
> I really need help im a teacher in vocational education, and with my students we are stuck.
> 
> Thanks

> <https://github.com/processing/p5.js/issues/7423>
>
> \### Increasing access
> 
> By now is a headache to get to work p5.js libraries in Vi…te, and when i got to work in Vite, then it doesnt work in Vercel...
> So would be nice that same tutorial or examples would work in local vite, and Vercel.
> 
> Thanks
> 
> \### Which types of changes would be made?
> 
> \- \[\] Breaking change (Add-on libraries or sketches will work differently even if their code stays the same.)
> \- \[\] Systemic change (Many features or contributor workflows will be affected.)
> \- \[\] Overdue change (Modifications will be made that have been desirable for a long time.)
> \- \[X\] Unsure (The community can help to determine the type of change.)
> 
> \### Most appropriate sub-area of p5.js?
> 
> \- \[\] Accessibility
> \- \[\] Color
> \- \[X\] Core/Environment/Rendering
> \- \[\] Data
> \- \[\] DOM
> \- \[\] Events
> \- \[\] Image
> \- \[\] IO
> \- \[\] Math
> \- \[\] Typography
> \- \[\] Utilities
> \- \[\] WebGL
> \- \[X\] Build process
> \- \[\] Unit testing
> \- \[\] Internationalization
> \- \[\] Friendly errors
> \- \[\] Other (specify if possible)
> 
> \### What's the problem?
> 
> Make p5.js work in Vite and Vercel is a headache
> 
> \### What's the solution?
> 
> One way of working and writing code, fully compatible with Vite and Vercel
> 
> \### Pros (updated based on community comments)
> 
> \- Using standard of industry tools like vite, vercel
> 
> 
> \### Cons (updated based on community comments)
> 
> None so far
> 
> \### Proposal status
> 
> Under review
