Skip to content

Translation support - #18

Merged
KhanShaheb34 merged 14 commits into
mainfrom
feat/i18n-bengali-english
Jun 18, 2026
Merged

KhanShaheb34 merged 14 commits into
mainfrom
feat/i18n-bengali-english

Conversation

@KhanShaheb34

@KhanShaheb34 KhanShaheb34 commented Jun 4, 2026 •

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Bengali-first bilingual site with locale-aware routing, language selector/flags, and a localized subscribe modal that sends locale.
  • Locale-aware SEO

    • Localized metadata, hreflang alternates, locale-aware sitemap/robots, and per-locale OG image generation/paths.
  • Content

    • Many new English tutorial chapters (caching, CDN, networking, load balancer, replication, partitioning, scaling) plus About/Introduction.
  • Documentation

    • New TRANSLATING guide and updated CONTRIBUTING/README describing Bengali-first translation workflow.
  • Bug Fixes

    • Unsubscribe/return links use configured base URL; unsubscribe hashing upgraded to HMAC verification.
  • Chores

    • Added local tooling ignore rule and switched site font to Bricolage Grotesque; added OG generation script.

@vercel

vercel Bot commented Jun 4, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
montu-mia Ready Ready Preview, Comment Jun 10, 2026 6:09pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 229e6f0e-15bd-406b-9d25-79b46c1b5c40

📥 Commits

Reviewing files that changed from the base of the PR and between e57b84f and 368def6.

📒 Files selected for processing (1)
  • src/lib/email-hash.ts

📝 Walkthrough

Walkthrough

Adds Bengali-first i18n infra (constants, i18n, typed dictionaries, middleware), converts layouts/pages/components to language-aware routes, makes metadata/sitemap/robots and OG tooling locale-aware, adds English MDX content, and provides translation documentation and scripts.

Changes

Bengali-default internationalization rollout

Layer / File(s) Summary
All changes (single checkpoint)
src/lib/constants.ts, src/lib/i18n.ts, src/lib/dictionaries.ts, src/dictionaries/*.json, src/lib/layout.shared.tsx, src/proxy.ts, src/lib/source.ts, src/app/[lang]/layout.tsx, src/app/[lang]/sd/layout.tsx, src/app/[lang]/(home)/page.tsx, src/app/[lang]/sd/[[...slug]]/page.tsx, src/app/sitemap.ts, src/app/robots.ts, src/app/global.css, src/components/*, src/app/actions.ts, src/app/api/unsubscribe/route.ts, src/components/subscribe-modal.tsx, scripts/*, content/sd/**/*.en.mdx, TRANSLATING.md, CONTRIBUTING.md, README.md, CLAUDE.md, .gitignore, package.json, emails/README.md, next.config.mjs, src/lib/email-hash.ts
Implements Bengali-default i18n contracts and URL helpers; exports Fumadocs i18n and UI provider; adds typed dictionaries and bn/en JSON; wires i18n into content loader and middleware; converts root/docs layouts and pages to [lang]-scoped routes with localized metadata and providers; updates sitemap/robots to use BASE_URL and hreflang alternates; localizes components and subscribe/unsubscribe flows; refactors OG scripts to generate per-locale images; adds extensive English MDX docs and translation guidance; updates docs and ignores .gstack/.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • KhanShaheb34/montu-mia#17: Related changes to OG image generation and chapter filtering logic used by scripts/generate-og-images.ts.
  • KhanShaheb34/montu-mia#4: Overlaps layout/footer behavior and theme/language toggle work for docs layouts.
  • KhanShaheb34/montu-mia#15: Overlapping newsletter subscription/unsubscribe work affecting src/app/actions.ts and unsubscribe routes.

Poem

🐰 I nibble strings in Bengali and English,

Paths wear /en or stay home in bn,
Flags pop open, fonts and OGs appear,
Dictionaries hum, middleware steers the gear,
Hopping translations — code carrots near!

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/i18n-bengali-english

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (2)
src/components/language-flag-dropdown.tsx (1)

11-11: ⚡ Quick win

Use the project cn utility import path.

Import cn from @/lib/cn here to match the project’s class-merging contract.

As per coding guidelines, src/**/*.tsx: use custom component utilities from src/lib/cn.ts for class merging.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/language-flag-dropdown.tsx` at line 11, The import for the
class-merge utility in language-flag-dropdown.tsx currently pulls `cn` from
"`@/lib/utils`"; change it to import `cn` from the project's canonical module
"`@/lib/cn`" so the component uses the standard class-merging implementation
(update the import statement that references `cn` in this file).
src/components/language-toggle.tsx (1)

10-13: ⚡ Quick win

Use @/lib/cn for class merging in this TSX component.

This import bypasses the project’s class-merging utility contract and can diverge merge behavior from the rest of the UI.

Suggested diff
-import { cn } from "`@/lib/utils`";
+import { cn } from "`@/lib/cn`";

As per coding guidelines, "src/**/*.tsx: Configure Tailwind via @tailwindcss/postcss plugin and use custom component utilities from src/lib/cn.ts for class merging".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/language-toggle.tsx` around lines 10 - 13, The component
imports the class-merge helper from "`@/lib/utils`" instead of the project
standard "`@/lib/cn`"; update the import in language-toggle.tsx to import the cn
function from "`@/lib/cn`" (keeping the existing symbol name `cn`), verify any
usages of `cn(...)` in the LanguageToggle component remain unchanged and
type-check, and ensure no other helper methods from "`@/lib/utils`" are relied on
in this file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLAUDE.md`:
- Line 96: Update the CLAUDE.md OG images line to reflect actual behavior of
scripts/generate-og-images.ts and generate-index-og.ts: state that for the
default locale (Bengali) files are written to public/og/sd/... (unprefixed),
while for all other entries in LOCALES output is written under
public/og/<lang>/sd/...; mention that the scripts read *.<lang>.mdx (falling
back to the Bengali title) and produce the two distinct paths accordingly.
- Around line 73-82: Update the intra-file routing guidance so every page route
is shown under the `[lang]` segment: change the docs paths that currently
reference `src/app/sd/[[...slug]]/page.tsx` and `src/app/sd/layout.tsx` to the
localized equivalents under `src/app/[lang]/sd/` (e.g.,
`src/app/[lang]/sd/[[...slug]]/page.tsx` and `src/app/[lang]/sd/layout.tsx`),
and clarify that the root layout is `src/app/[lang]/layout.tsx` (there is no
`src/app/layout.tsx`); keep the locale-independent API/robots/sitemap entries
as-is.

In `@content/sd/introduction.en.mdx`:
- Around line 4-11: The frontmatter tags in content/sd/introduction.en.mdx are
too generic; update the tags array (the existing "tags:" block) to include
page-specific English SEO phrases such as "system design introduction", "system
design basics", "bangla system design", and "software architecture fundamentals"
alongside the current tags so the MDX follows the content/sd/**/*.mdx guideline
to bridge English search queries with Bengali content; keep the existing generic
tags and append these new, query-aligned terms.

In `@scripts/generate-og-images.ts`:
- Around line 198-206: The OG cleanup step in scripts/generate-og-images.ts (the
block using LOCALES, ogDirForLocale and filterArg) removes public/og/.../sd
recursively including sd/index/image.png even though generate-index-og.ts later
recreates those; fix by either adjusting the generate-og npm script in
package.json to run generate-index-og.ts after scripts/generate-og-images.ts, or
change the cleanup in scripts/generate-og-images.ts to skip removing any
sd/index directory (e.g., detect and preserve path segments matching "sd/index"
instead of removing the entire sd tree) so that slug === "index" outputs from
generate-index-og.ts are not deleted.

In `@src/app/`[lang]/layout.tsx:
- Around line 6-17: The layout currently imports and instantiates
Bricolage_Grotesque into the variable bricolage and sets CSS variable
--font-bricolage; replace that with the required Outfit font and the correct CSS
variable names: import Outfit from next/font/google (use the exported name used
in repo), create an outfit const (e.g., const outfit = Outfit({...})) with the
same options (latin subset, appropriate weights, display: "swap", preload: true)
and set variable: "--font-outfit"; also ensure Noto_Sans_Bengali is instantiated
with variable: "--font-bengali" (not --font-bricolage) so global styles expect
--font-outfit and --font-bengali; update any usage of bricolage or
--font-bricolage elsewhere in this file (and the other referenced block at lines
~77-90) to use outfit and the new CSS variable names.

In `@src/components/language-flag-dropdown.tsx`:
- Line 25: The aria-label on the language switcher is hardcoded ("Change
language"); replace it with a localized string from the app dictionaries by
importing and using getDictionary(lang) and the appropriate key (e.g.,
languageSwitcherLabel) from the JSON dictionaries
(src/dictionaries/{bn,en}.json) inside the LanguageFlagDropdown component so the
aria-label is populated from the returned dictionary for the current lang;
update dictionaries to include the new key if missing and ensure the component
reads the current lang and passes dict.languageSwitcherLabel into the aria-label
prop.

In `@src/components/language-toggle.tsx`:
- Line 30: Replace the hardcoded aria-label in the LanguageToggle component with
a localized string: add a key like "changeLanguage" to both
src/dictionaries/en.json and src/dictionaries/bn.json, load the dictionary via
getDictionary(lang) (or accept the passed-in dict/lang prop per the component
pattern) and use that dictionary key for the aria-label on the trigger element
instead of the literal "Change language"; update the LanguageToggle component to
reference the dictionary key (e.g., dict.changeLanguage) so the aria-label is
localized for both EN and BN.

In `@src/lib/layout.shared.tsx`:
- Around line 32-38: In baseOptions, normalize the incoming lang once and use
that normalized value for both metadata lookup and nav.url to avoid mismatched
meta and URL; e.g., compute a normalizedLocale (using LOCALE_META[lang as
Locale] ?? LOCALE_META.bn to decide locale key or derive 'bn' fallback) and then
use that normalizedLocale to get meta and to build nav.url (so nav.url uses "/"
for 'bn' and `/${normalizedLocale}` for others) ensuring consistency between
meta and URL.

In `@TRANSLATING.md`:
- Line 21: The in-page anchor `[Add a new language](`#add-a-new-language`)`
doesn't match the actual heading `## C. Add a new language`, so update either
the link or the heading for consistency: either change the link to `[Add a new
language](`#c-add-a-new-language`)` to match the rendered anchor for `## C. Add a
new language`, or rename the heading to `## Add a new language` so the existing
`#add-a-new-language` fragment works; ensure you update the exact markdown text
`## C. Add a new language` or the link target
`#add-a-new-language`/`#c-add-a-new-language` accordingly.

---

Nitpick comments:
In `@src/components/language-flag-dropdown.tsx`:
- Line 11: The import for the class-merge utility in language-flag-dropdown.tsx
currently pulls `cn` from "`@/lib/utils`"; change it to import `cn` from the
project's canonical module "`@/lib/cn`" so the component uses the standard
class-merging implementation (update the import statement that references `cn`
in this file).

In `@src/components/language-toggle.tsx`:
- Around line 10-13: The component imports the class-merge helper from
"`@/lib/utils`" instead of the project standard "`@/lib/cn`"; update the import in
language-toggle.tsx to import the cn function from "`@/lib/cn`" (keeping the
existing symbol name `cn`), verify any usages of `cn(...)` in the LanguageToggle
component remain unchanged and type-check, and ensure no other helper methods
from "`@/lib/utils`" are relied on in this file.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5dd9d5c-c61d-4761-8adc-b6add5835a7e

📥 Commits

Reviewing files that changed from the base of the PR and between 3ab1992 and c511612.

⛔ Files ignored due to path filters (33)
  • public/flags/bd.svg is excluded by !**/*.svg
  • public/flags/us.svg is excluded by !**/*.svg
  • public/og/en/sd/about/image.png is excluded by !**/*.png
  • public/og/en/sd/caching/benefits/image.png is excluded by !**/*.png
  • public/og/en/sd/caching/challenges/image.png is excluded by !**/*.png
  • public/og/en/sd/caching/eviction/image.png is excluded by !**/*.png
  • public/og/en/sd/caching/image.png is excluded by !**/*.png
  • public/og/en/sd/caching/invalidation/image.png is excluded by !**/*.png
  • public/og/en/sd/caching/strategies/image.png is excluded by !**/*.png
  • public/og/en/sd/cdn/benefits/image.png is excluded by !**/*.png
  • public/og/en/sd/cdn/how-it-works/image.png is excluded by !**/*.png
  • public/og/en/sd/cdn/image.png is excluded by !**/*.png
  • public/og/en/sd/cdn/push-vs-pull/image.png is excluded by !**/*.png
  • public/og/en/sd/data-partitioning/image.png is excluded by !**/*.png
  • public/og/en/sd/data-partitioning/sharding-techniques/image.png is excluded by !**/*.png
  • public/og/en/sd/data-partitioning/trade-offs/image.png is excluded by !**/*.png
  • public/og/en/sd/data-partitioning/types/image.png is excluded by !**/*.png
  • public/og/en/sd/hook/image.png is excluded by !**/*.png
  • public/og/en/sd/introduction/image.png is excluded by !**/*.png
  • public/og/en/sd/load-balancer/benefits/image.png is excluded by !**/*.png
  • public/og/en/sd/load-balancer/how-it-works/image.png is excluded by !**/*.png
  • public/og/en/sd/load-balancer/image.png is excluded by !**/*.png
  • public/og/en/sd/load-balancer/types/image.png is excluded by !**/*.png
  • public/og/en/sd/networking/http-versions/image.png is excluded by !**/*.png
  • public/og/en/sd/networking/http-vs-https/image.png is excluded by !**/*.png
  • public/og/en/sd/networking/image.png is excluded by !**/*.png
  • public/og/en/sd/networking/tcp-vs-udp/image.png is excluded by !**/*.png
  • public/og/en/sd/replication/image.png is excluded by !**/*.png
  • public/og/en/sd/replication/methods/image.png is excluded by !**/*.png
  • public/og/en/sd/replication/redundancy/image.png is excluded by !**/*.png
  • public/og/en/sd/replication/replication/image.png is excluded by !**/*.png
  • public/og/en/sd/scaling/image.png is excluded by !**/*.png
  • public/og/en/sd/what-is-system-design/image.png is excluded by !**/*.png
📒 Files selected for processing (32)
  • .gitignore
  • CLAUDE.md
  • CONTRIBUTING.md
  • README.md
  • TRANSLATING.md
  • content/sd/introduction.en.mdx
  • content/sd/meta.en.json
  • scripts/generate-index-og.ts
  • scripts/generate-og-images.ts
  • src/app/[lang]/(home)/layout.tsx
  • src/app/[lang]/(home)/page.tsx
  • src/app/[lang]/layout.tsx
  • src/app/[lang]/sd/[[...slug]]/page.tsx
  • src/app/[lang]/sd/layout.tsx
  • src/app/actions.ts
  • src/app/api/unsubscribe/route.ts
  • src/app/global.css
  • src/app/layout.tsx
  • src/app/robots.ts
  • src/app/sitemap.ts
  • src/components/ai/page-actions.tsx
  • src/components/language-flag-dropdown.tsx
  • src/components/language-toggle.tsx
  • src/components/subscribe-modal.tsx
  • src/dictionaries/bn.json
  • src/dictionaries/en.json
  • src/lib/constants.ts
  • src/lib/dictionaries.ts
  • src/lib/i18n.ts
  • src/lib/layout.shared.tsx
  • src/lib/source.ts
  • src/proxy.ts
💤 Files with no reviewable changes (1)
  • src/app/layout.tsx

Comment thread CLAUDE.md
Comment thread CLAUDE.md Outdated
Comment thread content/sd/introduction.en.mdx
Comment thread scripts/generate-og-images.ts
Comment thread src/app/[lang]/layout.tsx
Comment thread src/components/language-flag-dropdown.tsx Outdated
Comment thread src/components/language-toggle.tsx Outdated
Comment thread src/lib/layout.shared.tsx Outdated
Comment thread TRANSLATING.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/app/[lang]/layout.tsx (1)

38-39: ⚡ Quick win

Localize the description using getDictionary(lang).

The description is currently hardcoded with Bengali and English text, which doesn't adapt to the user's locale. Server components should call getDictionary(lang) to access locale-specific translations.

💡 Suggested implementation
 export async function generateMetadata({
   params,
 }: LayoutProps<"/[lang]">): Promise<Metadata> {
   const { lang } = await params;
   const meta = LOCALE_META[lang as Locale] ?? LOCALE_META.bn;
+  const dict = await getDictionary(lang);

   return {
     title: {
       template: `%s | ${meta.siteName}`,
       default: meta.siteName,
     },
-    description:
-      "মন্টু মিয়াঁর সিস্টেম ডিজাইন - A System Design Book in Bengali. Learn system design concepts with simple analogies.",
+    description: dict.metadata.description,

Ensure src/dictionaries/bn.json and src/dictionaries/en.json include a metadata.description field with locale-appropriate text.

As per coding guidelines, server components should call getDictionary(lang) directly to access UI string translations from src/dictionaries/{lang}.json.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/`[lang]/layout.tsx around lines 38 - 39, Update the hardcoded
metadata.description in the exported metadata in layout.tsx to load
locale-specific text by calling getDictionary(lang) inside the server component;
specifically import and call getDictionary(lang) and use the returned
dictionary's metadata.description (e.g., dict.metadata.description) instead of
the hardcoded string so the description is localized for both bn and en
dictionaries. Ensure src/dictionaries/bn.json and src/dictionaries/en.json
contain metadata.description keys.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/app/`[lang]/layout.tsx:
- Around line 38-39: Update the hardcoded metadata.description in the exported
metadata in layout.tsx to load locale-specific text by calling
getDictionary(lang) inside the server component; specifically import and call
getDictionary(lang) and use the returned dictionary's metadata.description
(e.g., dict.metadata.description) instead of the hardcoded string so the
description is localized for both bn and en dictionaries. Ensure
src/dictionaries/bn.json and src/dictionaries/en.json contain
metadata.description keys.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eac2adeb-861e-4641-993c-552560b3c2d4

📥 Commits

Reviewing files that changed from the base of the PR and between c511612 and 5269f3b.

📒 Files selected for processing (2)
  • src/app/[lang]/layout.tsx
  • src/lib/constants.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/constants.ts

- Localize language-switcher aria-labels via dictionaries (a11y.changeLanguage)
- Import cn from @/lib/cn (project convention) in the switcher components
- Normalize unknown locale once in baseOptions (consistent meta + nav.url)
- Chain generate-index-og after generate-og-images so the index OG isn't deleted
- Docs: fix stale src/app/sd paths -> [lang], clarify per-locale OG output paths,
  update font note to Bricolage Grotesque (intentional), fix TRANSLATING anchor

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… balancing, caching, CDN, and replication topics
- Replace generic intro.en.mdx tags with page-specific English SEO keywords
  (CodeRabbit nitpick on PR #18)
- TRANSLATING.md: add a prominent 'tell the story, not the words' section
  documenting the adaptive, story-based translation approach (slang/idioms/
  cultural references localized, voice preserved, famous quotes restored)
- TRANSLATING.md: update the tags guidance to recommend specific English SEO tags

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
content/sd/cdn/index.en.mdx (1)

1-12: ⚡ Quick win

Add description field for better SEO and social sharing.

While the description field is optional in the frontmatter schema, it's used by the metadata generator to populate OpenGraph and Twitter card descriptions. Without it, social media previews and search results will lack a description.

Consider adding a description like:

 ---
 title: "CDN, Now What?"
+description: "Understanding Content Delivery Networks and how they reduce latency"
 tags:
   - Content Delivery Network

Based on learnings: Create MDX files in content/sd/ directory with required frontmatter fields: title (required, Bengali), description (optional, Bengali), and tags (optional, English keywords array)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/sd/cdn/index.en.mdx` around lines 1 - 12, The frontmatter for the MDX
file is missing a description field used by the metadata generator; update the
frontmatter to include a Bengali "description" key alongside the existing
"title" and "tags" entries (keep "title" in Bengali as required and "tags" as an
English array), populating "description" with a concise Bengali sentence
suitable for OpenGraph/Twitter preview so social previews and search results
have a proper description.
content/sd/cdn/how-it-works.en.mdx (1)

1-11: ⚡ Quick win

Add description field for better SEO and social sharing.

The description field is used by the metadata generator for OpenGraph and Twitter card descriptions. Adding one will improve social media previews and search results.

Consider:

 ---
 title: "How Does a CDN Actually Work?"
+description: "Understanding Origin and Edge servers in CDN architecture"
 tags:
   - CDN Architecture

Based on learnings: Create MDX files in content/sd/ directory with required frontmatter fields: title (required, Bengali), description (optional, Bengali), and tags (optional, English keywords array)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/sd/cdn/how-it-works.en.mdx` around lines 1 - 11, The MDX frontmatter
is missing the optional description field used by the metadata generator; update
the frontmatter block (the YAML between the leading --- markers that currently
contains title and tags) to include a description: "<short Bengali description>"
so that OpenGraph/Twitter cards and SEO use it; ensure you keep the existing
title and tags keys unchanged and add description as a plain string value in
Bengali.
content/sd/cdn/push-vs-pull.en.mdx (1)

1-11: ⚡ Quick win

Add description field for better SEO and social sharing.

The description field is used by the metadata generator for OpenGraph and Twitter card descriptions. Adding one will improve social media previews and search results.

Consider:

 ---
 title: "Push or Pull?"
+description: "Comparing Pull and Push CDN caching strategies"
 tags:
   - Push CDN

Based on learnings: Create MDX files in content/sd/ directory with required frontmatter fields: title (required, Bengali), description (optional, Bengali), and tags (optional, English keywords array)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/sd/cdn/push-vs-pull.en.mdx` around lines 1 - 11, The frontmatter is
missing a description field used by the metadata generator; update the MDX
frontmatter (near the existing title and tags fields) to include a description:
provide a short Bengali sentence for the description key (YAML string) so
OpenGraph/Twitter cards get a proper preview; keep title in Bengali and tags as
an English keywords array and add description between or after title/tags in the
YAML block.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@content/sd/load-balancer/types.en.mdx`:
- Around line 4-14: The frontmatter "tags" array currently contains 11 entries
which exceeds the 4–8 keyword guideline; reduce and replace it with 4–8 focused,
English technical keywords that map Bengali content to common search queries.
Edit the frontmatter tags in content/sd/load-balancer/types.en.mdx (the "tags"
array) to remove lower-value or redundant terms and keep core concepts like
"Load Balancer", "Hardware Load Balancer" OR "Software Load Balancer" (choose
one), "Layer 4 Load Balancer" OR "Layer 7 Load Balancer" (choose the most
relevant), and one or two platform/tool keywords such as "Nginx" or
"HAProxy"/"AWS" so the array contains between 4 and 8 concise tags.

In `@content/sd/networking/http-versions.en.mdx`:
- Around line 4-13: The frontmatter tags array currently has nine entries;
reduce them to 4–8 focused SEO keywords by removing redundancies and less
essential items. Edit the frontmatter tags array to keep core technical terms
such as: "HTTP", "HTTP/2", "HTTP/3", "QUIC", "TCP", and "Networking" (or pick a
subset of 4–6 from these), and remove redundant or overlapping tags like "HTTP
Versions" and any least-relevant terms to meet the 4–8 guideline.

---

Nitpick comments:
In `@content/sd/cdn/how-it-works.en.mdx`:
- Around line 1-11: The MDX frontmatter is missing the optional description
field used by the metadata generator; update the frontmatter block (the YAML
between the leading --- markers that currently contains title and tags) to
include a description: "<short Bengali description>" so that OpenGraph/Twitter
cards and SEO use it; ensure you keep the existing title and tags keys unchanged
and add description as a plain string value in Bengali.

In `@content/sd/cdn/index.en.mdx`:
- Around line 1-12: The frontmatter for the MDX file is missing a description
field used by the metadata generator; update the frontmatter to include a
Bengali "description" key alongside the existing "title" and "tags" entries
(keep "title" in Bengali as required and "tags" as an English array), populating
"description" with a concise Bengali sentence suitable for OpenGraph/Twitter
preview so social previews and search results have a proper description.

In `@content/sd/cdn/push-vs-pull.en.mdx`:
- Around line 1-11: The frontmatter is missing a description field used by the
metadata generator; update the MDX frontmatter (near the existing title and tags
fields) to include a description: provide a short Bengali sentence for the
description key (YAML string) so OpenGraph/Twitter cards get a proper preview;
keep title in Bengali and tags as an English keywords array and add description
between or after title/tags in the YAML block.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 654f4350-1e0b-498d-84b9-32caa3c1f1df

📥 Commits

Reviewing files that changed from the base of the PR and between a92860f and 5615ea1.

📒 Files selected for processing (37)
  • content/sd/about.en.mdx
  • content/sd/caching/benefits.en.mdx
  • content/sd/caching/challenges.en.mdx
  • content/sd/caching/eviction.en.mdx
  • content/sd/caching/index.en.mdx
  • content/sd/caching/invalidation.en.mdx
  • content/sd/caching/meta.en.json
  • content/sd/caching/strategies.en.mdx
  • content/sd/cdn/benefits.en.mdx
  • content/sd/cdn/how-it-works.en.mdx
  • content/sd/cdn/index.en.mdx
  • content/sd/cdn/meta.en.json
  • content/sd/cdn/push-vs-pull.en.mdx
  • content/sd/data-partitioning/index.en.mdx
  • content/sd/data-partitioning/meta.en.json
  • content/sd/data-partitioning/sharding-techniques.en.mdx
  • content/sd/data-partitioning/trade-offs.en.mdx
  • content/sd/data-partitioning/types.en.mdx
  • content/sd/hook.en.mdx
  • content/sd/introduction.en.mdx
  • content/sd/load-balancer/benefits.en.mdx
  • content/sd/load-balancer/how-it-works.en.mdx
  • content/sd/load-balancer/index.en.mdx
  • content/sd/load-balancer/meta.en.json
  • content/sd/load-balancer/types.en.mdx
  • content/sd/networking/http-versions.en.mdx
  • content/sd/networking/http-vs-https.en.mdx
  • content/sd/networking/index.en.mdx
  • content/sd/networking/meta.en.json
  • content/sd/networking/tcp-vs-udp.en.mdx
  • content/sd/replication/index.en.mdx
  • content/sd/replication/meta.en.json
  • content/sd/replication/methods.en.mdx
  • content/sd/replication/redundancy.en.mdx
  • content/sd/replication/replication.en.mdx
  • content/sd/scaling.en.mdx
  • content/sd/what-is-system-design.en.mdx
✅ Files skipped from review due to trivial changes (8)
  • content/sd/networking/meta.en.json
  • content/sd/cdn/meta.en.json
  • content/sd/replication/meta.en.json
  • content/sd/load-balancer/meta.en.json
  • content/sd/data-partitioning/meta.en.json
  • content/sd/networking/index.en.mdx
  • content/sd/caching/meta.en.json
  • content/sd/load-balancer/benefits.en.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • content/sd/introduction.en.mdx

Comment thread content/sd/load-balancer/types.en.mdx Outdated
Comment thread content/sd/networking/http-versions.en.mdx
- Trim over-length tag lists to <=8 keywords (load-balancer/types: 10->8,
  networking/http-versions: 9->8)
- Add a page-specific English description to the 13 chapters that lacked one
  (used for OpenGraph/Twitter cards and search snippets)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tauhid-hasan-dev

Copy link
Copy Markdown

Looks good to me .

@MehrazRumman MehrazRumman left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine ! But do you think more tests are needed here ?

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/`[lang]/sd/[[...slug]]/page.tsx:
- Around line 55-56: The markdown action URL passed to ViewOptions is not
locale-aware; replace markdownUrl={`${page.url}.mdx`} with a locale-aware URL by
calling buildUrl(lang, `${page.url}.mdx`) (or localePath(lang,
`${page.url}.mdx`) if you need a relative href) so the ViewOptions actions use
the current locale; update the prop in the ViewOptions invocation in page.tsx
accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 275303b9-8c1a-477c-b61d-52feb2a7a20a

📥 Commits

Reviewing files that changed from the base of the PR and between 2e0f822 and f496963.

📒 Files selected for processing (6)
  • CLAUDE.md
  • TRANSLATING.md
  • src/app/[lang]/sd/[[...slug]]/page.tsx
  • src/components/ai/page-actions.tsx
  • src/dictionaries/bn.json
  • src/dictionaries/en.json
💤 Files with no reviewable changes (1)
  • src/dictionaries/bn.json
✅ Files skipped from review due to trivial changes (4)
  • src/dictionaries/en.json
  • src/components/ai/page-actions.tsx
  • CLAUDE.md
  • TRANSLATING.md

Comment thread src/app/[lang]/sd/[[...slug]]/page.tsx
… with locale validation and improved accessibility.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/email-hash.ts (1)

56-64: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve configuration-error propagation in verifyEmailHash.

Line 56 catches UNSUBSCRIBE_SECRET failures and returns false, which makes src/app/api/unsubscribe/route.ts return 403 instead of its intended 500 server-configuration response.

🔧 Proposed fix
 export function verifyEmailHash(email: string, hash: string): boolean {
-  try {
-    return (
-      safeEqual(generateEmailHash(email), hash) ||
-      safeEqual(generateLegacyEmailHash(email), hash)
-    );
-  } catch (error) {
-    console.error("Hash verification failed:", error);
-    return false;
-  }
+  return (
+    safeEqual(generateEmailHash(email), hash) ||
+    safeEqual(generateLegacyEmailHash(email), hash)
+  );
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/email-hash.ts` around lines 56 - 64, The try/catch in verifyEmailHash
is swallowing configuration errors (like missing UNSUBSCRIBE_SECRET) and
returning false; change it so configuration errors propagate: in
src/lib/email-hash.ts update the catch in verifyEmailHash to rethrow errors
related to UNSUBSCRIBE_SECRET (e.g., if error.message or error.name references
UNSUBSCRIBE_SECRET or config) and only return false for genuine verification
failures; alternatively remove the try/catch entirely so errors from
generateEmailHash/generateLegacyEmailHash bubble up. Ensure you reference the
generateEmailHash, generateLegacyEmailHash and UNSUBSCRIBE_SECRET symbols when
making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/lib/email-hash.ts`:
- Around line 56-64: The try/catch in verifyEmailHash is swallowing
configuration errors (like missing UNSUBSCRIBE_SECRET) and returning false;
change it so configuration errors propagate: in src/lib/email-hash.ts update the
catch in verifyEmailHash to rethrow errors related to UNSUBSCRIBE_SECRET (e.g.,
if error.message or error.name references UNSUBSCRIBE_SECRET or config) and only
return false for genuine verification failures; alternatively remove the
try/catch entirely so errors from generateEmailHash/generateLegacyEmailHash
bubble up. Ensure you reference the generateEmailHash, generateLegacyEmailHash
and UNSUBSCRIBE_SECRET symbols when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c343b613-0ef2-49d9-b0c6-090ae6ce90c2

📥 Commits

Reviewing files that changed from the base of the PR and between f496963 and e57b84f.

⛔ Files ignored due to path filters (20)
  • public/og/en/sd/about/image.png is excluded by !**/*.png
  • public/og/en/sd/caching/benefits/image.png is excluded by !**/*.png
  • public/og/en/sd/caching/challenges/image.png is excluded by !**/*.png
  • public/og/en/sd/caching/image.png is excluded by !**/*.png
  • public/og/en/sd/caching/invalidation/image.png is excluded by !**/*.png
  • public/og/en/sd/cdn/benefits/image.png is excluded by !**/*.png
  • public/og/en/sd/cdn/how-it-works/image.png is excluded by !**/*.png
  • public/og/en/sd/cdn/image.png is excluded by !**/*.png
  • public/og/en/sd/cdn/push-vs-pull/image.png is excluded by !**/*.png
  • public/og/en/sd/data-partitioning/sharding-techniques/image.png is excluded by !**/*.png
  • public/og/en/sd/data-partitioning/types/image.png is excluded by !**/*.png
  • public/og/en/sd/hook/image.png is excluded by !**/*.png
  • public/og/en/sd/index/image.png is excluded by !**/*.png
  • public/og/en/sd/load-balancer/benefits/image.png is excluded by !**/*.png
  • public/og/en/sd/load-balancer/how-it-works/image.png is excluded by !**/*.png
  • public/og/en/sd/load-balancer/image.png is excluded by !**/*.png
  • public/og/en/sd/networking/http-vs-https/image.png is excluded by !**/*.png
  • public/og/en/sd/networking/image.png is excluded by !**/*.png
  • public/og/en/sd/replication/image.png is excluded by !**/*.png
  • public/og/en/sd/what-is-system-design/image.png is excluded by !**/*.png
📒 Files selected for processing (20)
  • CLAUDE.md
  • TRANSLATING.md
  • emails/README.md
  • next.config.mjs
  • scripts/generate-index-og.ts
  • scripts/generate-og-images.ts
  • src/app/[lang]/(home)/layout.tsx
  • src/app/[lang]/(home)/page.tsx
  • src/app/[lang]/layout.tsx
  • src/app/[lang]/sd/[[...slug]]/page.tsx
  • src/app/llms.mdx/[lang]/[[...slug]]/route.ts
  • src/app/sitemap.ts
  • src/components/ai/page-actions.tsx
  • src/components/language-flag-dropdown.tsx
  • src/components/language-toggle.tsx
  • src/lib/constants.ts
  • src/lib/dictionaries.ts
  • src/lib/email-hash.ts
  • src/lib/layout.shared.tsx
  • src/lib/source.ts
✅ Files skipped from review due to trivial changes (3)
  • src/app/llms.mdx/[lang]/[[...slug]]/route.ts
  • CLAUDE.md
  • TRANSLATING.md
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/components/language-flag-dropdown.tsx
  • src/lib/source.ts
  • src/app/[lang]/sd/[[...slug]]/page.tsx
  • src/components/language-toggle.tsx
  • scripts/generate-index-og.ts
  • src/app/[lang]/(home)/page.tsx
  • src/lib/layout.shared.tsx

…ilHash

The inner try/catch caught the missing-secret config error and returned
false, so the unsubscribe route returned 403 "invalid hash" and its 500
"server configuration error" path was dead code. Remove it: a wrong hash
still returns false (safeEqual never throws), and the only throw path is
the missing secret, which the route already catches and surfaces as 500.

Addresses CodeRabbit review on PR #18.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@KhanShaheb34
KhanShaheb34 merged commit 3375c39 into main Jun 18, 2026
4 checks passed

This branch was successfully deployed

1 active deployment
Preview — 368def6a Deployed Jun 10, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants