How to add (almost) any codepen to your WordPress website

How to add (almost) any codepen to your WordPress website

Disclaimer: I will be using Divi for this one because that’s what my site ended up having the most tutorials for, but this will work in any page builder as long as you use the equivalent module/block/widget.

I’ve seen this question asked a lot in the WP groups I frequent: “How do I take this codepen and use it on my site?”

The fb post I had started to help with was wondering about this pen in particular.

And check out the working demo page here

So yeah, let’s break this down.

This tutorial will be aimed at beginners who are not as well versed in all the languages and how they work together. I’ll explain the basics here.

HTML5, or the language of modern websites, are basically made with 3 different coding languages (or script, or markup, depending on who you ask) HTML, CSS, and JavaScript.

HTML is the basic structure. It’s what wraps the content so the other two languages can find their places. CSS is what makes the design. It gives instructions on how the HTML should be displayed. JS is what gives it interactivity. JS can detect what the user is doing and react accordingly.

All three have advanced syntaxes that people have put together so it’s easier to write, but usually needs a compiler for it to render.

Common ones are like HAML or even the Emmet plugin for writing quick HTML, and SASS, SCSS, (which you can learn here) or LESS can be compiled into CSS, and there are tons of JS libraries that allow you to write for certain things more easily than just vanilla JS, such as jQuery or Svelte, and to get into special purpose libraries, GSAP, MagicScroll, etc. So you load the library, and write the JS that uses that library. (Node, React, and Angular are more full stack-y, so I didn’t include them in this quick list)

OK. That’s enough background info. Let’s get into the pen itself.

Watch the video below, or just keep reading to see it in written step-by-step form.

Looking at the pen, you will see three windows on top.

  • Left: HTML
  • Center: CSS
  • Right: JS

(Remember the three web languages?)

So, what you’re seeing there is the HTML structure needed for the JS to find the target and do its thing. The CSS style sheet that allows the space to be large enough to work, and the JS itself.

We can start easily by adding the html to a code module, and if you don’t want to add the CSS site-wide then just drop it inside style tags.

BUT, remember, in order for any non-vanilla JS to work, you’d need to load the library first. So, check out what’s been loaded by clicking on the small cog on top of the JS window. Ah, GSAP, JQ, and Physics2D. We’ll need to load those too.

To load a JS library, usually the GitHub page or wherever it lives will have something like a cdn link you can use to enqueue it in WP.

(Note: cdn links are good because if it’s a popular library like jQuery or GSAP, chances are users will already have it cached in their computers, so your load times will reap the benefits. But it will cause problems if the site has to be accessed from China due to the Great Firewall, so just keep that in mind.)

Here’s how you enqueue it in WP. (If you’re using a child theme or a custom plugin, and you can edit the functions.php file) This will apply site-wide. 

/* This should be INSIDE the php file inside the php declarations */
add_action('wp_footer', 'your_function_nametwo');
function your_function_nametwo(){
  wp_enqueue_script( 'jquery00', '' );

Here’s how you add it via html. (In a code module, or just in the theme settings) If it’s in a code module, it’ll just apply to that page. If you add it in the footer, then it’ll be site-wide.

<script src=""></script>

In the case of this pen, load all three libraries. (NOTE: I just realized this after trying this live, that the physics2D doesn’t work without a GSAP membership (it’s a premium library) so just the first two..)

Then add the JS inside a script tag.

To put everything into ONE code module here’s what you can copy paste into a code module:

<div id="panel">
  <canvas id="magic-dust"></canvas>
#panel {
  width: 100%;
  height: 100vh;
  background-color: #000;
<script src=""></script>
<script src=""></script>
    var end_panel = document.querySelector("#panel");
    var end_cv = document.getElementById("magic-dust");
    var end_ctx = end_cv.getContext("2d");
    var end_cvWidth = parseInt(window.getComputedStyle(end_panel).width, 10); // get width without "px"
    var end_cvHeight = parseInt(window.getComputedStyle(end_panel).height, 10); // get height without "px"
    var resolution = window.devicePixelRatio || 1;
    var sprites = [];
    var toRad = Math.PI / 180;
    var fx_tl;

    // resize for retina
    function start_fx() {
        // particles
            "circle",         // texture
            1777,               // total sprites
            50,50, 50,50,     // width-+, height-+
            0,1600, 0,1600,   // start position x-+, y-+
            4,12, 0,360,      // velocity-+, angle-+
            .1,2.5, .2,.8,  // scale start-+, end-+
            360, 0,0,         // rotation start, end-+
            1.7,24,             // duration-+
            .1, 2,            // fade in, out duration
            0.1,              // gravity
            12,             // delay+ inbetween sprites
            -1,               // repeat sprite animation (-1 = infinite)
            0                 // delay timeline
$(document).mousemove(function(e) {
        var x = e.pageX;
        var y = e.pageY;
        var scrollPosition = $(window).scrollTop()

    function init_fx(textureSpr, totalSpr, minWidth,maxWidth, minHeight,maxHeight, xMin,xMax, yMin,yMax, veloMin,veloMax, angleMin,angleMax, startScaleMin,startScaleMax, endScaleMin,endScaleMax, rotStart, rotEndMin,rotEndMax, minDur,maxDur, fadeInDur, fadeOutDur, gravitySpr, delaySpr, repeatSpr, delayTl) {
        // generate sprites
        for (var i = 0; i < totalSpr; i++) {
            var widthSpr = randomInt(minWidth, maxWidth);
            var heightSpr = randomInt(minHeight, maxHeight);
            // define texture
            var texture = createShape(textureSpr, i);

        createMagicDust = (x,y,n) => {
            for (var i = 0; i < n; i++) {
                var texture = createShape(textureSpr, Math.floor(Math.random()*10));

        // start rendering animation
        function createSprite(x,y,t) {
            var width  = (texture.naturalWidth  || texture.width  || 0) / resolution;
            var height = (texture.naturalHeight || texture.height || 0) / resolution;
            var duration = t || randomNr(minDur, maxDur);
            // limit angle if needed
            var angleNr;
            if (angleMin == -90 && angleMax == -270) {
                angleNr = Math.random() < 0.5 ? 90 : 270; // only up or down
            } else if (angleMin == -0 && angleMax == -180)  {
                angleNr = Math.random() < 0.5 ? 0 : 180; // only left or right
            } else {
                angleNr = randomNr(angleMin, angleMax);
            // create a new timeline for the sprite
            fx_tl = gsap.timeline({
                delay: t ? 0 : randomNr(delaySpr),
                repeat: t ? 0 : repeatSpr,
                repeatDelay: randomNr(1)
            // sprite object default properites
            var sprite = {
                animation: fx_tl,
                texture: texture,
                width: width,
                height: height,
                alpha: 0,
                rotation: randomNr(rotStart),
                scale: randomNr(startScaleMin, startScaleMax),
                originX: t ? .2 : 0.5,
                originY: t ? .3 : 0.5,
                x: x || randomNr(xMin, xMax),
                y: y || randomNr(yMin, yMax),

            // animate to
            fx_tl.add("start", delayTl)
                .to(sprite, t ? 0.3 : fadeInDur, {alpha: 1, ease:Power0.easeIn}, "start")
                .to(sprite, duration, {
                    rotation: 180 * randomNr(rotEndMin, rotEndMax),
                    scale: randomNr(endScaleMin, endScaleMax),
                    physics2D: {
                        velocity: randomNr(veloMin, veloMax),
                        angle: angleNr,
                        gravity: gravitySpr,
                }, "start")
                // fade out
                .to(sprite, t ? 1.5 : fadeOutDur, {
                    alpha: 0,
                    delay: t ? 1.5 : duration-fadeOutDur
                }, 0);

            return sprite;

        function createShape(textureSpr, i) {
            // Create offscreen canvas
            var canvas = document.createElement("canvas");
            var context = canvas.getContext("2d");
            canvas.width = widthSpr * resolution;
            canvas.height = heightSpr * resolution;
            var radius = widthSpr / 2;
            var gradient = context.createRadialGradient(radius, radius, 0, radius, radius, radius);
            if (i % 3 === 0){
                gradient.addColorStop(0, "rgba(177,255,252,0.75)");
                gradient.addColorStop(0.15, "rgba(177,255,252,0.1)");
            } else if (i % 5 === 0){
                gradient.addColorStop(0, "rgba(202,76,255,0.6)");
                gradient.addColorStop(0.1,  "rgba(202,76,255,0.1)");
            } else {
                gradient.addColorStop(0, "rgba(102,219,214,0.6)");
                gradient.addColorStop(0.1,  "rgba(102,219,214,0.1)");
            gradient.addColorStop(0.65, "rgba(0,0,0,0)");
            context.fillStyle = gradient;
            context.fillRect(0, 0, widthSpr, heightSpr);
                return canvas;

    function renderCv() {
        end_ctx.clearRect(0, 0, end_cvWidth, end_cvHeight);
        for (var i = 0; i < sprites.length; i++) {
            var sprite = sprites[i];
            // Skip rendering sprite if it has no alpha
            if (!sprite.alpha) {
            var offsetX = sprite.originX * sprite.width;
            var offsetY = sprite.originY * sprite.height;
            end_ctx.translate(sprite.x + offsetX, sprite.y + offsetY);
            end_ctx.rotate(sprite.rotation * toRad);
            end_ctx.scale(sprite.scale, sprite.scale);
            end_ctx.globalAlpha = sprite.alpha;
            end_ctx.drawImage(sprite.texture, -offsetX, -offsetY);

    function resizeCv() {
        end_cv.width  = end_cvWidth * resolution;
        end_cv.height = end_cvHeight * resolution;  = end_cvWidth + "px"; = end_cvHeight + "px";
        end_ctx.scale(resolution, resolution);

    function randomNr(min, max) {
        if (max === undefined) { max = min; min = 0; }
        if (min > max) { var tmp = min; min = max; max = tmp; }
        return min + (max - min) * Math.random();

    function randomInt(min, max) {
        if (max === undefined) { max = min; min = 0; }
        if (min > max) { var tmp = min; min = max; max = tmp; }
        return Math.floor(min + (max - min + 1) * Math.random());

And there you go.🙂

All done.

Extra notes:

GSAP has a membership that allows you to use all the libraries, you’ll need that to get the third one to work. The only difference is the stars don’t float as nicely.

Every page builder (including Gutenberg) has a code module. NOT a code display module (like a <pre>) but a direct html module. Use that.

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. Hey, do I need to enqueue the library in the functions.php file AND add the cdn link as the src of a script tag, or do I just do one or the other?


    • Hi Jared, you should be good to do either. The difference would only be that using funcitons.php would result in the extra files loading on every page, and using the scrip tag in the code module would result in it loading only on that page. Hope that makes sense!

  2. Hi PK, thank you so much for this tutorial. I am simply dangerous enough with HTML. With CSS and Javascript, I’m a complete noob. I was provided a codepen by a vender with a “here you go, good luck” message. Thanks to your tutorial, I was able to implement it successfully. In addition to the general input of the code, the gamechanger was adding the source code first. Again, thank you!

    • Hi ChikQ, that’s great to hear! I’m so happy it worked out well for you! Thank you for your kind words!

  3. Hey, PK! Thanks so much for taking the time to write this up for us. Good stuff!

    If I may, it would be great if your code wasn’t such a large font. Also, I’d be interesting in hearing what you are using to present code. Especially with the large font, a ‘copy’ button on the code would be great. I’m using the Prismatic plugin for WordPress and absolutely love it.

    Thanks again, this is great, and also thanks for all your help in the FB groups!

    • Hi Terry, great seeing you here! I use Syntax Highlighter because it had php and sass, and I just kept using it. I just changed the font size, and made it easier to double click to copy the whole code snippet. Thanks for mentioning it! Also I might have to look into that plugin you mentioned. Thanks!

  4. Hi PK,
    Can you please explain how to target specific sections/rows with this code?
    e.g. if I want to use this as a section backgound, let’s say class=”et_pb_section_1″
    I’m sure it’s easy but im a total noob. Thanks!

    • Hi Matt, the better (and easier) way is to add “panel” to the module or section ID, and the inside a code module and get that to stretch out where you need it. (reduce the paddings of the columns and rows) hope that helps!

New tutorials

Why no ads?

Hi, I'm PK, and I maintain and publish content on this site for two reasons.

  1. To give back to the community. I learned so much from people's tutorials and StackOverflow that I wanted to contribute and help others.

  2. To provide a more structured learning experience. People struggle to find the course that guides them from start to finish, based off of real life experience, and my courses provide that.

The only "ads" I have here are for my own courses, and maybe an affiliate link, but that's it. They fund the website resources and provide more motivation for me to produce better content.

Any bit of interest helps. Even sharing with your friends, suggesting my courses to your developer or designer, or subscribing to my YT channel, or joining our Discord. Thanks and I'll see you around!

There's a newsletter!

Sign up to the newsletter for the occasional updates on courses, products, tutorials, and sales.