Html codes
Photo
CodePen Blog
416: Upgrading Next.js & React
Shaw and Chris are on the show to talk about the thinking and challenges behind upgrading these rather important bits of technology in our stack. We definitely think of React version upgrades and Next.js version upgrades as different things. Sometimes they are prerequisites. The Next.js ones are a bit more important as 1) the docs for the most recent version tend to be the best and 2) it involves server side code which is important for security reasons. Never has any of it been trivially easy.
Time Jumps
* 00:15 p.s. we’re on YouTube
* 01:09 Do we need to upgrade React? NextJS?
* 08:46 Next 15 requires React 19
* 11:38 What’s our TypeScript situation?
* 17:49 Next 16 upgrade and Turbopack woes
* 34:57 Next’s MCP server
416: Upgrading Next.js & React
Shaw and Chris are on the show to talk about the thinking and challenges behind upgrading these rather important bits of technology in our stack. We definitely think of React version upgrades and Next.js version upgrades as different things. Sometimes they are prerequisites. The Next.js ones are a bit more important as 1) the docs for the most recent version tend to be the best and 2) it involves server side code which is important for security reasons. Never has any of it been trivially easy.
Time Jumps
* 00:15 p.s. we’re on YouTube
* 01:09 Do we need to upgrade React? NextJS?
* 08:46 Next 15 requires React 19
* 11:38 What’s our TypeScript situation?
* 17:49 Next 16 upgrade and Turbopack woes
* 34:57 Next’s MCP server
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Flag animation</title>
<style>
:root{
--w: 900px;
}
html,body{height:100%;margin:0;font-family:Arial, sans-serif}
.page{
min-height:100vh;display:flex;align-items:center;justify-content:center;flex-direction:column;background:#f2faff;padding:20px;
}
.flag-wrap{width:min(95vw,var(--w));max-width:1000px;}
svg{display:block;width:100%;height:auto;border:1px solid #ccc;border-radius:6px;overflow:visible}
.controls{margin-top:12px;display:flex;gap:10px}
button{padding:6px 12px;border-radius:6px;border:0;background:#0b5ed7;color:#fff;font-weight:600;cursor:pointer}
button.secondary{background:#eee;color:#111}
@media (prefers-reduced-motion: reduce){
.wave-filter{filter:none !important}
}
</style>
</head>
<body>
<div class="page">
<div class="flag-wrap">
<svg id="uzflag" viewBox="0 0 900 450" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="wave" x="-20%" y="-20%" width="140%" height="140%" class="wave-filter">
<feTurbulence id="turb" baseFrequency="0.009 0.02" numOctaves="2" seed="2" type="fractalNoise" result="noise" />
<feDisplacementMap in="SourceGraphic" in2="noise" scale="18" xChannelSelector="R" yChannelSelector="G"/>
</filter>
</defs>
<rect width="900" height="450" fill="#ffffff" />
<g id="flagGroup" filter="url(#wave)">
<rect x="0" y="0" width="900" height="150" fill="#1EB3E6" />
<rect x="0" y="150" width="900" height="6" fill="#C82B2B" />
<rect x="0" y="156" width="900" height="138" fill="#FFFFFF" />
<rect x="0" y="294" width="900" height="6" fill="#C82B2B" />
<rect x="0" y="300" width="900" height="150" fill="#118C4E" />
</g>
</svg>
<div class="controls">
<button id="playBtn">Play</button>
<button id="pauseBtn" class="secondary">Stop</button>
</div>
</div>
</div>
<script>
(function(){
const turb = document.getElementById('turb');
const playBtn = document.getElementById('playBtn');
const pauseBtn = document.getElementById('pauseBtn');
let running = true;
let start = performance.now();
let rafId;
const params = {
baseX: 0.009,
baseY: 0.02
}
function animate(now){
const t = (now - start);
const bx = params.baseX + Math.sin(t * 0.0006) * 0.003;
const by = params.baseY + Math.cos(t * 0.0009) * 0.006;
turb.setAttribute('baseFrequency', bx + ' ' + by);
rafId = requestAnimationFrame(animate);
}
rafId = requestAnimationFrame(animate);
playBtn.addEventListener('click', ()=>{
if(!running){ running = true; rafId = requestAnimationFrame(animate); }
});
pauseBtn.addEventListener('click', ()=>{
if(running){ running = false; cancelAnimationFrame(rafId); }
});
const mq = window.matchMedia('(prefers-reduced-motion: reduce)');
if(mq.matches){ if(running){ cancelAnimationFrame(rafId); } }
})();
</script>
</body>
</html>
Which of the following inventions inspired the creation of the first computer?
Anonymous Quiz
86%
A) The abacus 🧮
0%
B) The light bulb 💡
14%
C) The steam engine 🚂
0%
D) The typewriter ⌨️
❤1
CodePen Blog
Chris’ Corner: Browser Feature Testing
It’s interesting to me to think about during a lot of the web’s evolution, there were many different browser engines (more than there are now) and they mostly just agreed-on-paper to do the same stuff. We focus on how different things could be cross-browser back then, which is true, but mostly it all worked pretty well. A miracle, really, considering how unbelievably complicated browsers are.
Then we got standards and specifications and that was basically the greatest thing that could have happened to the web. So we put on our blue beanies and celebrate that, which also serves as a reminder to protect these standards. Don’t let browsers go rogue, people!
Then, still later, we actually got tests.
In retrospect, yes, obviously, we need tests. These are now web-platform-tests (WPT), and they help all the browser engines make sure they are all doing the right thing. Amazing.
(Side note: isn’t it obnoxious how many billions of dollars goes into newfangled browsers without any of them contributing or funding actual browser engine work?)
I only recently just saw browserscore.dev by Lea Verou as well. Yet another tool to keep browsers honest. Frankly I’m surprised how low all browsers score on those tests. I read in one of Lea’s commit messages “We’re not WPT, we’re going for breadth not depth.” which I found interesting. The Browser Score tests run in the browser and pretty damn fast. I haven’t run them myself, but I have a feeling WPT tests take… a while.
How can we improve on all this? Well a gosh-darn excellent way to do it is what the companies that make browsers have already been doing for a number of years: Interop. Interop is a handshake deal from these companies that they are going to get together and pick some great things that need better testing and fixed up implementations and then actually do that work. Interop 2025 looks like it went great again.
It’s that time again now, and these browser companies are asking for ideas for Interop 2026. If you have something that bugs you how it works cross-browser, now is a great time to say so. Richard has some great ideas that seem like perfect fits for the task.
Godspeed, ya’ll. We can’t all be like Keith and just do it ourselves.
Chris’ Corner: Browser Feature Testing
It’s interesting to me to think about during a lot of the web’s evolution, there were many different browser engines (more than there are now) and they mostly just agreed-on-paper to do the same stuff. We focus on how different things could be cross-browser back then, which is true, but mostly it all worked pretty well. A miracle, really, considering how unbelievably complicated browsers are.
Then we got standards and specifications and that was basically the greatest thing that could have happened to the web. So we put on our blue beanies and celebrate that, which also serves as a reminder to protect these standards. Don’t let browsers go rogue, people!
Then, still later, we actually got tests.
In retrospect, yes, obviously, we need tests. These are now web-platform-tests (WPT), and they help all the browser engines make sure they are all doing the right thing. Amazing.
(Side note: isn’t it obnoxious how many billions of dollars goes into newfangled browsers without any of them contributing or funding actual browser engine work?)
I only recently just saw browserscore.dev by Lea Verou as well. Yet another tool to keep browsers honest. Frankly I’m surprised how low all browsers score on those tests. I read in one of Lea’s commit messages “We’re not WPT, we’re going for breadth not depth.” which I found interesting. The Browser Score tests run in the browser and pretty damn fast. I haven’t run them myself, but I have a feeling WPT tests take… a while.
How can we improve on all this? Well a gosh-darn excellent way to do it is what the companies that make browsers have already been doing for a number of years: Interop. Interop is a handshake deal from these companies that they are going to get together and pick some great things that need better testing and fixed up implementations and then actually do that work. Interop 2025 looks like it went great again.
It’s that time again now, and these browser companies are asking for ideas for Interop 2026. If you have something that bugs you how it works cross-browser, now is a great time to say so. Richard has some great ideas that seem like perfect fits for the task.
Godspeed, ya’ll. We can’t all be like Keith and just do it ourselves.
CodePen
Chris’ Corner: Browser Feature Testing
It’s interesting to me to think about during a lot of the web’s evolution, there were many different browser engines (more than there are now) and they mostly just agreed-on-paper to do…
Which programming language was created first?
Anonymous Quiz
38%
A) C
13%
B) Python
25%
C) Java
25%
D) Fortran
🔥 Top 10 JavaScript Cybersecurity Libraries
1️⃣ Crypto-JS – Encryption & hashing
2️⃣ jsSHA – SHA hashing
3️⃣ node-forge – RSA, TLS, certificates
4️⃣ zxcvbn – Password strength
5️⃣ DOMPurify – XSS protection
6️⃣ jsrsasign – JWT & digital signatures
7️⃣ JSEncrypt – RSA encryption
8️⃣ sql.js – SQLite in browser
9️⃣ nmap-scanner – Port scanning
🔟 Burp JS API – Pentest extensions
@Html_codee
1️⃣ Crypto-JS – Encryption & hashing
2️⃣ jsSHA – SHA hashing
3️⃣ node-forge – RSA, TLS, certificates
4️⃣ zxcvbn – Password strength
5️⃣ DOMPurify – XSS protection
6️⃣ jsrsasign – JWT & digital signatures
7️⃣ JSEncrypt – RSA encryption
8️⃣ sql.js – SQLite in browser
9️⃣ nmap-scanner – Port scanning
🔟 Burp JS API – Pentest extensions
@Html_codee
Html codes
Photo
CodePen Blog
Chris’ Corner: Cursors
CSS has a bunch of cursors already. Chances are, you’re not using them as much as you should be. Well, should is a strong word. I can’t cite any evidence offhand that special cursors is some absolute boon to user experience or accessibility. But it certainly seems like a nice touch. Like:
Or
These cursors are actually supplied by your OS, and thus can be altered by the OS. That’s a good thing, as some OSs let you bump up the size of the cursor (with a
Looking around at our 2.0 Beta editor, I can see lots of CSS-provided cursor changes.
https://blog.codepen.io/wp-content/uploads/2025/11/CleanShot-2025-11-13-at-10.26.48.gif
I’m pretty pleased with those!
An interesting aspect of “custom” cursors is that they are only obviously a problem if you replace the actual cursor itself. That doesn’t rule out doing things in addition or next to the cursor. Our own Rachel Smith’s site has rainbow paint splotches shoot out from behind the cursor, just for fun, but the cursor itself isn’t changed.
Kyle Lambert has a good article about doing useful things with the cursor with a particular focus on things Figma does. Here’s some of excerpts of good ideas:
When using the pen tool, the cursor displays preview points and potential path directions
During selection, the cursor indicates whether you can resize, rotate, or move elements
Each user’s cursor appears as a distinct color with their name attached, creating a sense of presence in the shared workspace. [… and they] act as a chat interface when a user types “/”
One of Figma’s latest features is a dynamic color picker interface. This provides a magnified view of the pixel selection, giving users a more precise color selection experience.
Just interesting stuff! Not sure we’re seeing quite as much cursor innovation elsewhere.
Chris’ Corner: Cursors
CSS has a bunch of cursors already. Chances are, you’re not using them as much as you should be. Well, should is a strong word. I can’t cite any evidence offhand that special cursors is some absolute boon to user experience or accessibility. But it certainly seems like a nice touch. Like:
.copy-button {
cursor: copy;
} Or
[disabled] {
cursor: not-allowed;
} These cursors are actually supplied by your OS, and thus can be altered by the OS. That’s a good thing, as some OSs let you bump up the size of the cursor (with a
url() value), for example, which is good for accessibility. You can set custom cursors as well, which won’t get bumped up, which is bad for accessibility. Looking around at our 2.0 Beta editor, I can see lots of CSS-provided cursor changes.
https://blog.codepen.io/wp-content/uploads/2025/11/CleanShot-2025-11-13-at-10.26.48.gif
I’m pretty pleased with those!
An interesting aspect of “custom” cursors is that they are only obviously a problem if you replace the actual cursor itself. That doesn’t rule out doing things in addition or next to the cursor. Our own Rachel Smith’s site has rainbow paint splotches shoot out from behind the cursor, just for fun, but the cursor itself isn’t changed.
Kyle Lambert has a good article about doing useful things with the cursor with a particular focus on things Figma does. Here’s some of excerpts of good ideas:
When using the pen tool, the cursor displays preview points and potential path directions
During selection, the cursor indicates whether you can resize, rotate, or move elements
Each user’s cursor appears as a distinct color with their name attached, creating a sense of presence in the shared workspace. [… and they] act as a chat interface when a user types “/”
One of Figma’s latest features is a dynamic color picker interface. This provides a magnified view of the pixel selection, giving users a more precise color selection experience.
Just interesting stuff! Not sure we’re seeing quite as much cursor innovation elsewhere.
❤1
Html codes
Photo
CodePen Blog
417: Iframe Allow Attribute Saga
There was a day not long ago where a Google Chrome browser update left any page with a CodePen Embed on it throwing a whole big pile of red JavaScript errors in the console. Not ideal, obviously.
The change was related to how the browser handles
We documented all this in a blog post so hopefully we could get some attention from Chrome on this, and for other browser makers as well since it affects all of us.
And I posted it on the ol’ social media:
Hi @developer.chrome.com 👋👋😬blog.codepen.io/2025/10/20/g…Having some iframe `allow` issues over here. Not sure if it's a "bug" to log, but we could use an assist.
— Chris Coyier (@chriscoyier.net) 2025-10-20T20:25:43.360Z
Huge thanks to Bramus Van Damme who saw this, triaged it at Chrome, and had a resolution within a day:
I followed up on this one with engineering (issues.chromium.org/issues/45408…), and we decided on a small tweak to only show these console messages when a reporting endpoint is set.The tweak landed in Chrome 143.0.7490.0 (current Canary)(See next message for before and after screenshots)
— Bramus (@bram.us) 2025-10-24T12:21:00.246Z
I think the patch is a great change so hats off to everyone involved for getting it done so quickly. It’s already in Canary and don’t really know when it’ll get the stable but that sure will be good. It follows how Safari is doing things where values that aren’t understood are just ignored (which we think is fine and inline with how HTML normally works).
Fortunately we were able to mitigate the problem a little until then. For most Embedded Pens, a
417: Iframe Allow Attribute Saga
There was a day not long ago where a Google Chrome browser update left any page with a CodePen Embed on it throwing a whole big pile of red JavaScript errors in the console. Not ideal, obviously.
The change was related to how the browser handles
allow attributes on iframes (i.e. ). CodePen was calculating the appropriate values inside an iframe for a nested iframe. That must have been a security issue of sorts, as now those values need to be present on the outside iframe as well.We documented all this in a blog post so hopefully we could get some attention from Chrome on this, and for other browser makers as well since it affects all of us.
And I posted it on the ol’ social media:
Hi @developer.chrome.com 👋👋😬blog.codepen.io/2025/10/20/g…Having some iframe `allow` issues over here. Not sure if it's a "bug" to log, but we could use an assist.
— Chris Coyier (@chriscoyier.net) 2025-10-20T20:25:43.360Z
Huge thanks to Bramus Van Damme who saw this, triaged it at Chrome, and had a resolution within a day:
I followed up on this one with engineering (issues.chromium.org/issues/45408…), and we decided on a small tweak to only show these console messages when a reporting endpoint is set.The tweak landed in Chrome 143.0.7490.0 (current Canary)(See next message for before and after screenshots)
— Bramus (@bram.us) 2025-10-24T12:21:00.246Z
I think the patch is a great change so hats off to everyone involved for getting it done so quickly. It’s already in Canary and don’t really know when it’ll get the stable but that sure will be good. It follows how Safari is doing things where values that aren’t understood are just ignored (which we think is fine and inline with how HTML normally works).
Fortunately we were able to mitigate the problem a little until then. For most Embedded Pens, a
Html codes
Photo
CodePen Blog
Chris’ Corner: Kagi Blog Typography
I’ve been using Kagi for search for the last many months. I just like the really clean search results. Google search results feel all junked up with ads and credit-bereft AI sludge, like the incentives to provide a useful experience have been overpowered by milking profit and a corporate mandates on making sure your eyeballs see as much AI as possible.
I’m also not convinced Google cares about AI slop. Like do they care if a movie review for Predator: Badlands was written by a human after actually watching the movie, or if Gemini farted out a review because the LLM knows basically what a movie review reads like. Me, I sure would like to know. So I’m pleased with Kagi’s SlopStop idea.
But I’ve managed to start this column with something I didn’t even really intend to talk about.
Naturally, I’d like to talk about the typography one Kagi’s blog (follow that SlopStop link). https://blog.codepen.io/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-10.55.58-AM-1024x604.png Look at those single words at the end of both of those headers. Looks off. I can’t remember if those are “widows” or “orphans”, but upon looking it up, it’s neither, it’s a “runt” (lol).
Obviously we can’t have that.
One option is to
Whatever — let’s not balance here anyway, let’s try
Honestly though it’s the
I think we bring in just a smidge more to help here. Kagi has a wonderful little dog logo, we bring her in on the title so it sets it apart. The nav can set inline with the title. We use the nice yellow brand color to better set the title and date, then let it ride. https://blog.codepen.io/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-11.33.19-AM-1024x939.png They should probably just get a CodePen account to work this stuff out right?
Chris’ Corner: Kagi Blog Typography
I’ve been using Kagi for search for the last many months. I just like the really clean search results. Google search results feel all junked up with ads and credit-bereft AI sludge, like the incentives to provide a useful experience have been overpowered by milking profit and a corporate mandates on making sure your eyeballs see as much AI as possible.
I’m also not convinced Google cares about AI slop. Like do they care if a movie review for Predator: Badlands was written by a human after actually watching the movie, or if Gemini farted out a review because the LLM knows basically what a movie review reads like. Me, I sure would like to know. So I’m pleased with Kagi’s SlopStop idea.
But I’ve managed to start this column with something I didn’t even really intend to talk about.
Naturally, I’d like to talk about the typography one Kagi’s blog (follow that SlopStop link). https://blog.codepen.io/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-10.55.58-AM-1024x604.png Look at those single words at the end of both of those headers. Looks off. I can’t remember if those are “widows” or “orphans”, but upon looking it up, it’s neither, it’s a “runt” (lol).
Obviously we can’t have that.
One option is to
text-wrap: balance; on the headers. Here’s what that looks like: https://blog.codepen.io/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-11.09.30-AM-1024x754.png Ehhhhhhhhh. Also not ideal. It makes those headers like half the width of the available space. Balancing is just way nicer with center-aligned headers. Which actually makes me think of how style queries should work with arbitrary styles… h1, h2, h3, h4 { /* doesn't actually work, style
queries only work on
--custom-properties */
@media style(text-align: center) {
text-wrap: balance;
}
} Whatever — let’s not balance here anyway, let’s try
text-wrap: pretty; (which lacks Firefox support). There we go: https://blog.codepen.io/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-11.22.41-AM-1024x608.png Better. The pretty values does a bunch of stuff, and runt-protection is among them.Honestly though it’s the
line-height that bugs me the most. It’s just too much for a big header. Let’s bring it in and even pull the letters a little bit with negative letter-spacing. https://blog.codepen.io/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-11.28.58-AM-1024x857.png Now we’ve got to fight hierarchy and organization a bit. All the text is pure black… fine. Everything is about the same distance away from each other… that’s a little weird. So we’re just leaning on text size and weight (and one little instance of italic). I think we bring in just a smidge more to help here. Kagi has a wonderful little dog logo, we bring her in on the title so it sets it apart. The nav can set inline with the title. We use the nice yellow brand color to better set the title and date, then let it ride. https://blog.codepen.io/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-11.33.19-AM-1024x939.png They should probably just get a CodePen account to work this stuff out right?
Which technology inspired the creation of touchscreen devices?
Anonymous Quiz
0%
A) Infrared sensors
0%
B) Radar technology
0%
C) Capacitive sensing
100%
D) Laser optics