The "Recently I Learned" is a collection of things I’ve discovered or figured out lately. Instead of writing a dedicated post for each one (unless it really deserves it), I’ve decided to compile them into a single summary. So here it is — the first edition of RIL (Recently I Learned).
1. Nuxt Content v3 custom ProseA
The default ProseA
component in Nuxt Content does not have the setting for target="_blank"
. Thanks to this blog post, I found out we can make custom ProseA that detect if the URL contains http
or https
then it'll bind target="blank"
for external link. I also added an icon if it's external icon.
2. Making a habit of selective data fetch
Yes, I know. I have this bad habit of "fetching everything just in case I need it later." But it turns out that’s not an efficient approach at all. It wastes resources, especially since most of that data never even gets seen by the user. I’m now trying to build a better habit: prefetching when needed, like on mouseenter
, and a bit more aggressive on caching.
Here's is my sub-note when I applied this to logoipsum.com
- Previously, I was loading all the data for each row even though most of it wasn’t needed at the initial state. The solution was simple: selectively load only the essential data upfront, and fetch the additional details only when viewing a single logo. The modal for a single logo now opens only after the additional data has been fetched.
- This behavior only applies when the entry point is the homepage. If the user lands directly on a single logo page (/artwork/id), then all necessary data is fetched by default using a dedicated API endpoint.
- One small improvement I’m happy with: I added a prefetch on mouseenter when the "See Details" button is hovered. In previous tests, clicking the button had a slight delay, and this completely fixed it.
- Also, I’ve added aggressive caching on both the server and browser. All server API routes now cache their payloads to reduce load and improve responsiveness.
3. Lazy loading NuxtImg will not work if placeholder is set
I didn't know this before, not until I see this issue on Nuxt repo. So yeah, if we want loading="lazy"
, we must remove the placeholder (line 9).
On second thought, it actually makes sense, doesn’t it? When we use a placeholder, the goal is to load something early by showing the placeholder first, then load and reveal the actual image. But loading="lazy"
does the opposite: it delays loading until the image is in the viewport. At that point, we don’t really need a placeholder anymore, do we? Or am I missing something? 🤔
4. Customizing ProsePre to customize Shiki highlighter
So I overrode the ProsePre
component with the following code. I added custom styling to the header to display the file name and language, along with a copy button. According to the Shiki documentation, this can be done using a transformer which I also learned recently, but I couldn’t find a way to make it work with Nuxt Content transformers. I also added line numbers, though I couldn’t find a "native" way to enable them, so I just used counter-increment
with plain CSS.
I recently updated the ProsePre
component with new feature: toggle wrap/nowrap code. Now maybe this deserves a dedicated post. We'll see.