Caching emotes for fast selection & embedding

#cache
#performance
#chat
#emotes

When building an emote picker or chat embed, fetching emotes on every render is expensive. The fix is to separate metadata from assets and cache both layers.

Cache emote metadata (IDs, names, URLs)

Store a lightweight index in memory (or Redis) for fast lookup by name.

// emoteCache.ts
type Emote = {
  id: string;
  name: string;
  url: string;
  provider: "twitch" | "bttv" | "7tv" | "local";
};

const emoteIndex = new Map<string, Emote>();

export function warmEmoteCache(emotes: Emote[]) {
  for (const emote of emotes) {
    emoteIndex.set(emote.name, emote);
  }
}

export function getEmoteByName(name: string) {
  return emoteIndex.get(name);
}

This lets your picker and message parser resolve :emote: tokens without touching the network.

Cache image assets at the edge or CDN

Serve emote images from a stable path and let the browser/CDN handle caching:

Cache-Control: public, max-age=31536000, immutable

Tailwind CSS !important modifier

#tailwindcss
#css

Make any utility important by adding a ! character to the beginning:

<p class="font-bold !font-medium">
  This will be medium even though bold comes later in the CSS.
</p>

Official Docs

nested backdrop-filter

#css

Backdrop filter tidak akan berhasil jika parent memiliki efek backdrop-filter juga.

issueworkaround

pre overflow: scroll inside flex

#css
#pre
#flex

Pernah pake overflow-x: scroll pada pre element tapi ngga ngaruh, malah parent yang ada scrollnya?

Mungkin parentnya didalem display: flex. Kalau iya, coba tambahin min-width: 0 pada parentnya.

Credit

import mdx file sebagai component

#react
#mdx

Import mdx file di component, caranya mirip seperti import component biasa:

import Contents from '@/mdx/Contents.mdx';

// Penggunaan
<Contents />

Ternyata ada di dokumentasinya. Biasakan membaca dulu ya gais jangan kaya saya wkwk.

:not() pseudo-class

#css
#selector

Pake :not() ini emang agak tricky, salah penggunaan hasilnya juga bisa ngga sesuai harapan.

Contoh, styling inline code dimana bukan children dari pre ataupun .code-block. Penggunaannya:

Don't
:not(pre), :not(.code-block) {
  > code {
    background-color: 'red';
  }
}
Do
:not(pre, .code-block) {
  > code {
    background-color: 'red';
  }
}

Turborepo dependsOn

#turborepo
#monorepo
"build": {
  "dependsOn": ["^lint", "test"]
},

dependsOn dengan ^ menandakan task dari package lain, sedangkan yang tanpa ^ task dari package itu sendiri.

Misal: app A pas mau build harus running tasks lint di semua package dependenciesnya, dan juga harus running task test app A itu sendiri.

e.target.valueAsNumber

#html
#js

Pakai e.target.valueAsNumber untuk otomatis mengembalikan nilai input sebagai number. Tidak perlu parseInt(e.target.value) lagi.