2025-04-30 20:00:00
Hey there! We're a quarter of the way through 2025 already, can you believe it? This weekend (May 3rd) I'll be in Rio de Janeiro trying to watch a free Lady Gaga concert in Copacabana beach. Fingers crossed I can actually see anything 🤞
For the Cool Links this month, we have a couple of "fun" ones, some web-dev related that were on my Read Later queue for a while, and some nuggets of wisdom on chaotic times.
Enjoy the reads!
This website simulates a TV schedule (with CRT-style filters!) with multiple channels, each featuring an interesting indie website. The programming changes often (just like shows on a tv channel), so it’s an interesting site to keep on your bookmarks and visit a few times a day.
The author here worries that so many people on Reddit are interacting with posters that are nothing more than robots, without any idea of that being the case. Even worse, some people are aware of that, but don't care.
I saw a comment in a brazilian forum that deeply resonated: “Maybe the biggest pain this realization causes is that, deep down, almost nobody cares about anything. We're the ones who are wrong for searching for meaning in environments dominated by chaos”.
It’s like image lazy loading, but for page elements! I’ve got to try this out sometime and measure the effectiveness of this technique. Depending on the results, this might end up as its own blog post ;)
Amazing step-by-step explanation on building Card components, with a special focus on accessibility. I love this kind of articles that explain the thinking behind every step and every line of code!
Card elements are everywhere and we all do them a bit differently. I’ll pay much more attention to the things mentioned here to ensure they’re as accessible as possible.
This site collects all kinds of designs for 404 pages found in the wild. Pretty cool source for inspiration or to admire other people's creativity!
We rely too much on software companies nowadays, and most of the popular ones are USA-based. With the USA becoming increasingly less trustworthy on an almost daily basis, people have started gathering EU-based alternatives to the most popular services.
This is interesting even if you're not based in Europe, as companies there are forced to respect your data and privacy by law.
Great article pointing out that “Views” are an useless metric and that the platforms that count it have zero incentive to not lie about them.
Thanks for tuning in, and see you next month!
2025-04-28 05:04:59
I really, really thought this was gonna be easy. But with front-end development, are things ever simple?
I've dropped a few hints here and there that I'm redesigning my website and blog. I'm also rewriting it from scratch, with Astro! It's a meta-framework, which means it takes care of the part that handles routing and data-fetching, but stays out of component and reactivity. It's like NextJS or SvelteKit.
The main appeal of Astro, though, is that it is framework-agnostic. You can use it as the base and then build all your components with React, Svelte, Vue, Vanilla JS, or even JQuery if that makes sense for you. It's one of the main appeals of Astro alongside active development, a clear project direction, and the whole zero client-side JS by default philosophy.
My soon-to-be-website uses Astro as its foundation, but keeps Svelte as the framework used for the components, to handle reactivity and just the overall template niceties. It also allows me to just port over existing components from my current SvelteKit website, and it's plug-and-play on Astro. Sweet!
Previously, I've used Histoire, a Vite-based simpler alternative to Storybook. It's fast and really easy to set up, which was the main reason I used it. It's not a fully-featured but I didn't need all the extra features of Storybook anyway. The thing is, development on that one is quite slow and it apparently doesn't work well with Svelte 5 yet. So, I figured I'd set up Storybook itself on my project. It's just a simple collection of Svelte components, right? How hard could it be?
Significantly.
[!info] The post below was written from my experience getting frustrated with the lack of proper documentation and a lot of trial and error. I was only able to get things working after a few hours digging into Storybook (and its plugins)'s documentation and source code, and a good deal of arguing with ChatGPT. I'm writing this guide so you don't have to go through all the hoops I did.
Also, I'm using Svelte on my examples as it's the framework I use, but I think the vast majority of this guide could apply to you if you use React, Vue, or none at all.
There are a lot of layers to the tech stack here. Astro uses Vite as a build tool to handle dependencies, dev servers, compiling, and whatever else it does. You might have heard of Webpack, which does the same. Vite is basically a newer, leaner version of that.
When you install Svelte (or React, or Vue) on an Astro project, you're actually just installing the Vite integration for that specific framework. Astro doesn't need to know what the client-side framework is because they're pretty much separated.
When you use Storybook, you likely don't want to interact with anything on the Astro side of things. You write stories for your components, and they will all be Svelte/React/Vue files that don't need Astro to work. Which is why there's no "Astro package" for Storybook, or any starting template.
Which means in this case, we want to setup Storybook for a Svelte + Vite project.
So, with my Astro + Svelte project in hands, these are the first steps I did:
npm create storybook@latest
npm uninstall @chromatic-com/storybook @storybook/experimental-addon-test @storybook/test @vitest/browser @vitest/coverage-v8 playwright vitest
This looks like it should be it, right? But if you run npm run storybook
, you'll see that it gives out an error. The error on the browser is a bit generic but on the terminal you'll see something like:
Internal server error: Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sure to name the file with the .jsx or .tsx extension. Plugin: vite:import-analysis File:(...)/node_modules/@storybook/svelte/dist/components/SlotDecorator.svelte
Vite is trying to compile the Storybook code but is erroneously identifying a closing </script>
tag as JSX syntax, even though it's a Svelte file. This hints to the fact that the Vite code that is running is not loading the plugin needed to make Svelte work (vite-plugin-svelte
). Astro does that automatically, but Storybook does not, as it just assumes a Svelte + Vite project would have that plugin installed as a dependency. So, to fix it, I:
npm install --save-dev @sveltejs/vite-plugin-svelte
.storybook/main.ts
file:~filename .storybook/main.ts
import type { StorybookConfig } from '@storybook/svelte-vite';
const config: StorybookConfig = {
"stories": [
"../src/**/*.stories.@(js|jsx|ts|tsx|svelte)"
],
"addons": [
"@storybook/addon-essentials",
"@storybook/addon-svelte-csf",
],
"framework": {
"name": "@storybook/svelte-vite",
"options": {}
},
"viteFinal": async (config) => {
// Needs to be dynamically imported
const { svelte } = await import('@sveltejs/vite-plugin-svelte');
config.plugins = config.plugins || [];
config.plugins.push(
svelte({
exclude: ["node_modules/@storybook/**"],
})
);
return config;
}
};
export default config;
And that should be enough for your stories to work!
If, like me, you're struggling a bit to find a good example of the latest syntax for Svelte stories (the older still works though), I found some good ones in the addon-svelte-csf project on GitHub.
If you have a global SCSS file that your components rely on, you can just add a line to .storybook/preview.ts
:
~filename .storybook/preview.ts
import '../src/styles/global.scss'; // Or whatever your file path is
{...}
If you use aliases set up in tsconfig.json in your components, for example so you can use @components/button
instead of src/components/button
, you either need to re-configure them for Storybook, or you can reuse the ones from tsconfig instead. To do that, you'll need:
npm install --save-dev vite-tsconfig-paths
~filename .storybook/main.ts
import type { StorybookConfig } from '@storybook/svelte-vite';
const config: StorybookConfig = {
{...}
"viteFinal": async (config) => {
// Needs to be dynamically imported
const tsconfigPaths = await import('vite-tsconfig-paths').then(m => m.default);
{...}
config.plugins.push(
{...}
tsconfigPaths({
projects: ['./tsconfig.json'],
})
);
return config;
}
{...}
};
export default config;
If your project uses aliases for SASS as well, you can alter the viteFinal
section of your .storybook/main.ts
file to make Vite resolve those aliases as well:
~filename .storybook/main.ts
import path from 'path';
{...}
"viteFinal": async (config) => {
{...}
// Add alias for SCSS @styles
config.resolve = config.resolve || {};
const stylesPath = path.resolve(process.cwd(), 'src/styles');
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({
find: '@styles',
replacement: stylesPath
});
} else {
config.resolve.alias = {
...(config.resolve.alias || {}),
'@styles': stylesPath
};
}
Looking back, it's not really a lot of steps to get it working. But it was a journey to get to this point. Hopefully I'm saving you some time on this!
Both parts of the stack are actually working as they should - Astro does the website part and stays out of the rest, Vite builds the tools, Svelte handles the components, and Storybook renders them. It was just a lack of either clear documentation or better error messages that kept me in the dark for a while. Hopefully there's more effort in improving this in the future!
I don't have comments on my blog, but feel free to shoot me an email if you have questions or suggestions. I'll be glad to help out (or be helped)!
2025-03-31 20:00:00
Hey there! Autumn is here in Brazil and the leaves have started to go yellow, which means it's my favorite season of the year! Mainly because it's neither too hot nor too cold, but also because it's very pretty.
I've prepped a selection of links to read through while you drink your coffee, tea, or whatever's your choice of beverage. The last one is a quite long video, but I highly recommend watching it!
pretend to be on your phone so that you pass as human, but actually do essentially nothing instead
Do you feel pressured to be on your phone all the time, so you can pass as a human? This neat web app allows you to do just that, but while doing absolutely nothing instead.
(honestly, it's a better use of your phone than scrolling through social media...)
Customizing <select>
elements is something every web developer has had to do, probably. And the thing about that is that... you really can't customize it. Or couldn't, until now.
Having to implement a custom look on this field was always, to me, the perfect definition of "reinventing the wheel". You gotta pick up this element that works reliably, is accessible, natively supported by all browsers, and users have been using for 30+ years, and then... build it from scratch, with JavaScript (which already kills the accessibility for some people).
Now, as of Chromium 135, you can finally customize them as you always expected you could! This will probably take a while to get to Safari and Firefox, but here's the cool thing: if those browsers don't support this new thing, the <select>
will just look like a normal field and work just as well. A perfect example of progressive enhancement!
Ahmad’s blog has been featured here a few times already, and here’s another gem! A fully interactive, well-written and just a plain joy to read article explaining different strategies to handle colors in CSS, focusing on all those little color variations we need to handle when building something.
In times where software “needs” to stand out rather than be familiar, we lose our heroes. Rest in peace, square checkboxes!
Sooo many times I’ve had to debug something in a npm package dependency of a project I’m working on, only to realize I need to change some of the code to make it work.
That’s usually a pain though, since you either have to open a pull request with a fix and wait for it to be merged, or setup your own fork of the package and host it somewhere.
This package aims to avoid that. It applies patches to other packages in your project, so you don’t have to go through the process of setting up a fork.
Really nice article that pretty much sums up the iPad situation: it is interesting hardware but that has pretty much no software that showcases what it does best.
The best iPad apps are... web apps. And the iPad's only available browser being Safari doesn't make things better.
This is an incredibly well-articulated rant about how recommendation algorithms are changing how our brains work. Automation is good for us and it’s everywhere, but what about when thinking, the very thing that makes us human, starts being automated?
Letting recommendation algorithms (that, as we all know, prioritize revenue) decide the information we get, the tone of that information, and the context of every social interaction is pretty much giving up on our autonomy.
The entire video is worth watching, but this part about context collapse was one of the most interesting bits. It makes perfect sense, but I had never thought of it this way:
Algorithmic feeds on social media are unfortunately quite good at fostering something known as context collapse. To understand this, imagine you’re dining in a restaurant and you’re close enough to a table of people to hear snippets of their conversation. You don’t know who any of the people at that table are, but if you manage to overhear them talk about something you’re really interested in, you might feel tempted to join their conversation. But in the context of a restaurant setting, that’s considered very rude, so it rarely ever happens.
On social media, though, the same kinds of quasi-private conversations between parties who know each other are happening all the time, but since the platform is just one big space and it might decide to put that conversation in front of random people, that social boundary of etiquette which is normally respected is just not there. And lots of conflicts happen as a result.
A really common one you might accidentally step into on social media happens when you stumble across a conversation among friends making sarcastic jokes with each other, but since you don’t know who those people are, you don’t have the context you need to recognize they’re joking. And so, if you reply with a serious critique, well, that’s a social misfire which some will react poorly to.
And that’s a pretty mild form of context collapse. It can be much, much worse when people want to discuss things like politics. And unless we realize recommendation algorithms are what’s fostering these reactionary conflicts, they’re going to continue so long as we use platforms in the ways that we do. It's for all these reasons that I believe algorithmic complacency is creating a crisis of both curiosity and human connection.
Thanks for tuning in another month, and I hope to see (write to? Be read by?) you again next month!
2025-02-28 20:00:00
Hey there! This month I brought a ton of links, probably a result of me trying to make a habit of checking my RSS reader every morning during breakfast. Let's get started!
Apparently when your indie app does not collect any amount of data, the data reapers get confused.
This is such a cool idea that I definitely want to copy in the future. I'm a bit wary of making so much private information public (especially dates), so I might not ever make this public anywhere. But still, a nice personal exercise and a perfect memento mori.
This is so cool! This website allows you to explore the 3D models of maps from a variety of old-ish games from the Wii, GameCube, DS and PS2 eras. If you’ve played any of them, it might be worth having a look. My favorite ones to explore like this were the maps from Pokémon HeartGold/SoulSilver and Platinum.
I recommend opening the site on a computer though. The touch controls aren’t great.
I love those joke programming languages. They're perfect examples that sometimes the only reason you need to build something is that you can.
Jake gives a really thorough explanation on view transitions, showing some of its shortcomings when animating some specific elements and how to fix them. View transitions are so nice 🤩
A fun exercise about making elements “pop out” of their containers with CSS without altering markup. Might not be useful if you can change the markup (as there are easier ways to do that), but learning this kind of approach is always good for expanding your repertoire.
That article about the faux containers lead me to this one. I knew about naming CSS grid areas, but I had no idea about the [area-start/end] pattern! You can set those explicitly or have them be automatically added by CSS. This is pretty cool!
The smoothness of a web application is an anti-indicator of its reliability and predictability as a web page.
your team almost certainly doesn’t have what it takes to out-engineer the browser. The browser will continuously improve the experience of plain HTML, at no cost to you, using a rendering engine that is orders of magnitude more efficient than JavaScript.
I remember when I first learned about SPAs and how amazing it seemed like to be able to have smooth transitions between pages. Then, as I started building and using them, it became apparent that those benefits also brought a lot of issues that took a lot of dev work to fix.
Luckily, with View Transitions, lazy loading, and predictive pre-rendering (start loading a page before you click on its link) that a lot of frameworks have now, we can have most of the SPA benefits without having to reinvent the wheel.
I've written about Container Queries before, but this article by Josh Comeau is great at giving even more examples of its utility. It's always nice to see what use cases other developers find for it.
HTML and CSS are my favorite parts of web development, and this article gives some great examples of why. Learning HTML is one of the best things you can do for your (web development) career, as it’s the most foundational block of a website and by itself can do most of the functionality you need. From HTML, you can progressively enhance the rest.
position: sticky is incredibly useful but I’ve had issues implementing it more than once. This article goes over some of the most common issues we can face with it and how we can fix them.
Cool article explaining a little bit about fonts and choosing them for your website/app. I’m still overwhelmed by the options, but I found the info in there to be interesting.
Abundance breeds boredom. When there’s no end of choices, each choice feels disappointing.
It was once assumed that digitization would liberate cultural artifacts from their physical containers. We’d be able to enjoy the wine without the bottles. What’s actually happened is different. We’ve come, as Goldsmith says, “to prefer the bottles to the wine.”
Worth a read if you use any kind of computer technology, really. It’s so weird how our ancient brain has adapted to the digital world - or maybe hasn’t adapted at all?
What a powerful read. Not really tech-related, but as someone who’s seen loved ones go down the same route as Sam did, it’s a very relatable, sad, albeit weirdly comforting, read.
Phew, that was a lot! Some of them were in my "Read later" queue for a while. I'll keep working on clearing up that queue and let's see how next month goes.
See you then!
2025-02-05 04:18:07
Easily one of the best parts of my atypical brain is its ability to dive deeply into subjects I find interesting. Throughout my life these subjects have been quite varied, with music, movies, art, history, and games all sucking me in at some point in my life.
With the internet it's always been quite easy for me to find stuff to read or watch about what I like. This allowed me to have a pretty in-depth knowledge about a lot of things.
Then, something changed. A change that started happening subtly but that's now pretty hard to ignore. People used to gather online in communities centered about things they liked. They'd be similarly excited about similar things, and discussing those things would usually be a joy.
Now it seems like people only go out of their way if it's to talk about things they hate. Communities centered around something remotely popular are gonna be filled with people complaining and pointing out every single flaw about it.
Why is that? I'm not sure. Maybe because people are so angry all the time? Digital drugs (a.k.a. social media) monetize your anger, so we're naturally more angry if we don't actively fight against it.
It's just something I realized and that made me stop and think about how I approach my interests now. If something brings me joy and I want to keep things that way, then it's just better to avoid online communities about that interest altogether. It just sucks that enjoying something with others is getting increasingly hard.
2025-01-31 20:00:00
Hey there! I hope your 2025 has started on a high note. What about some cool links to read during this weekend?
Henry's personal website is absolutely stunning! It has an unique design that is, above all, fun to explore. I miss exploring websites, instead of being guided through them.
Most of what Neal makes is pure gold and this is no exception. This game is no different than most of what you can find on your App Store, it’s just more honest about it…
Incredible article that not only explains the new-ish text-wrap: balance
and text-wrap: pretty
CSS properties in-depth, it also goes into the caveats those properties have. It's well-written, well illustrated, and interactive. What else could you want?
Ahmad once again writing the articles I wish I did. Another well-written and interactive article going in-depth on the also new-ish overflow: clip
CSS property. clip
has helped me implement designs more than once and it's so nice to have something that works just like I always expected overflow: hidden
to work.
This month was also a bit short on links as I have been mostly focused on work rather than learning. Here's hoping I can get back to finding more good links soon! 🤞