Lab Notes
A digital garden of code snippets, terminal commands, and quick fixes I use in production. Copypasta friendly.
Tailwind's built-in truncate utility only supports single-line truncation. To achieve exactly two (or N) lines of text truncation, you need to use the @tailwindcss/line-clamp plugin.
Install the plugin: npm install @tailwindcss/line-clamp
Add it to tailwind.config.js:
js// tailwind.config.jsmodule.exports = { plugins: [require("@tailwindcss/line-clamp")],};
Use the line-clamp-2 utility in your HTML:
html<p class="line-clamp-2 text-gray-700"> This text will automatically truncate after the second line with an ellipsis, ensuring a clean, consistent UI even with variable content lengths.</p>
Velite is a lightweight, file-based content layer built on top of Zod, designed to replace complex solutions like Contentlayer (now discontinued). It turns Markdown/MDX into strongly-typed JSON data.
Why use it?
Type Safety: Uses Zod schemas to validate and type content structure (e.g., ensuring a slug is always a string).
Simple Setup: Define your content schemas in velite.config.js and run the CLI.
Agnostic: Works great with Next.js, Astro, or any React framework.
js// velite.config.js snippetdefineCollection({ name: "Post", schema: s.object({ slug: s.slug(), title: s.string().max(99), content: s.mdx(), }),});
Indexes that are never used consume disk space and slow down INSERT/UPDATE/DELETE operations. This simple query identifies unused indexes that may be candidates for deletion.
Run this query to find indexes that haven't been used since the last database restart or statistics reset.
sqlSELECT relname AS table_name, indexrelid::regclass AS index_name, pg_size_pretty(pg_relation_size(indexrelid)) AS index_size, idx_scanFROM pg_stat_user_indexesWHERE idx_scan = 0 AND schemaname = 'public' -- Adjust schema if neededORDER BY pg_relation_size(indexrelid) DESC;
Note: Always verify with EXPLAIN ANALYZE before dropping an index in production!
When running next export or using the static output (output: 'export'), the built-in Next.js Image Component often results in blurry images due to missing image optimization features that rely on a server.
The Fix (Workaround):
Set the unoptimized prop to true on the <Image /> component.
This bypasses the Next.js optimization logic entirely, ensuring the image is served directly as provided in the public directory, and is sharp.
jsimport Image from "next/image";function MyComponent() { return ( <Image src="/images/static-hero.jpg" alt="Hero" width={800} height={600} unoptimized={true} // <-- The key fix for static exports /> );}
While Bash is the standard, Zsh (Z Shell) significantly boosts command-line productivity, especially when paired with frameworks like Oh My Zsh. It's often worth the switch for any serious developer.
Key Reasons for the Switch:
Smarter Autocompletion: Tab completion is incredibly powerful. It can autocomplete command arguments, git branches, file paths (even in the middle of a word), and context-aware options.
Syntax Highlighting: Commands turn green if they are valid before you even hit enter, catching typos instantly.
Powerful History: cd followed by a quick tab lets you jump to recent directories.
Theming: Oh My Zsh provides hundreds of themes and plugins for customizing the look and functionality (like showing current Git status in the prompt).
How to install Oh My Zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Here is how to do text gradients correctly in Tailwind so they handle multiline wrapping.
tsx<h1 className="bg-linear-to-r from-blue-500 to-purple-500 box-decoration-clone bg-clip-text text-transparent"> Hello World</h1>
Using 100vh on mobile often causes scroll issues because of the address bar. Here is the modern fix using dvh (Dynamic Viewport Height).
css.h-screen-safe { height: 100vh; /* Fallback */ height: 100dvh; /* Modern browsers */}
If you need to support older iOS versions, use the JS calculation method:
js// app.jsconst setHeight = () => { document.documentElement.style.setProperty( "--vh", `${window.innerHeight * 0.01}px`, );};window.addEventListener("resize", setHeight);