Skip to content

Conversation

@ComputelessComputer
Copy link
Collaborator

  • Replaced inline images with Image component in blog articles
  • Introduced Supabase URL transformation to proxy public storage images through /api/images
  • Added a reusable Callout MDX component with styles and icons
  • Updated image paths across multiple blog article MDX files to use local API routes

Introduce Supabase URL transformation to proxy public storage images through /api/images and update components/routes to use proxied paths. Add a reusable Callout MDX component (with styles and icons) and export it from mdx index. Wire Image into MDX content and replace inline Supabase avatar URLs with proxied API paths.

Changes were needed to avoid leaking direct Supabase storage URLs from the frontend, centralize image handling via a proxy, and provide a styled Callout component for MDX content.
Replace direct Supabase public image URLs with proxied local endpoints (/api/images/...) across multiple blog article MDX files. This avoids exposing the Supabase asset host directly and enables image proxying/caching, safer refactoring, and consistent URL handling across the site.
@netlify
Copy link

netlify bot commented Dec 1, 2025

Deploy Preview for hyprnote-storybook ready!

Name Link
🔨 Latest commit 6fbf652
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/692d12c37efd4800084a95db
😎 Deploy Preview https://deploy-preview-2030--hyprnote-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 1, 2025

📝 Walkthrough

Walkthrough

Replaces external image URLs with internal /api/images/... paths and converts HTML <img> tags to a standardized <Image> component across many MDX content and docs files. Adds a new MDX Callout component, re-exports it, and wires Callout and Image into blog MDX rendering; author avatar URLs also moved to /api/images/team/....

Changes

Cohort / File(s) Summary
Blog article image & markup migrations
apps/web/content/articles/ai-meeting-summary-tools.mdx, apps/web/content/articles/best-ai-meeting-assistant-for-taking-notes.mdx, apps/web/content/articles/best-ai-notetaker-for-in-person-meetings.mdx, apps/web/content/articles/best-ai-notetaker-for-microsoft-teams.mdx, apps/web/content/articles/best-ai-notetaker-for-zoom.mdx, apps/web/content/articles/best-ai-notetakers-google-meet.mdx, apps/web/content/articles/bot-free-ai-meeting-assistants.mdx, apps/web/content/articles/can-you-transcribe-meetings-without-sending-data-to-cloud.mdx, apps/web/content/articles/chatgpt-for-meeting-notes.mdx, apps/web/content/articles/enterprise-ai-notetaking-tools.mdx, apps/web/content/articles/fathom-ai-alternatives.mdx, apps/web/content/articles/fireflies-ai-alternatives.mdx, apps/web/content/articles/free-ai-notetakers.mdx, apps/web/content/articles/free-transcription-software.mdx, apps/web/content/articles/google-gemini-meeting-notes.mdx, apps/web/content/articles/granola-ai-alternatives.mdx, apps/web/content/articles/is-ai-notetaking-legal.mdx, apps/web/content/articles/is-fireflies-ai-safe.mdx, apps/web/content/articles/is-otter-ai-safe.mdx, apps/web/content/articles/local-ai-privacy-tools.mdx, apps/web/content/articles/meeting-minutes-software.mdx, apps/web/content/articles/meeting-preparation-checklist.mdx, apps/web/content/articles/open-source-meeting-transcription-software.mdx, apps/web/content/articles/otter-ai-alternatives.mdx, apps/web/content/articles/otter-ai-review.mdx, apps/web/content/articles/plaud-ai-alternatives.mdx, apps/web/content/articles/post-yc-slump.mdx, apps/web/content/articles/sales-ai-note-takers.mdx, apps/web/content/articles/see-zoom-meeting-history.mdx, apps/web/content/articles/tldv-review.mdx, apps/web/content/articles/zoom-ai-companion-review.mdx
Replaced external Supabase/public image URLs with internal /api/images/... paths; converted inline HTML <img> tags to framework Image components; updated coverImage frontmatter where applicable. Minor content tweaks in a few articles.
Blog article metadata & content edits
apps/web/content/articles/builders-win-ai-augmented-engineering.mdx, apps/web/content/articles/choosing-a-cms.mdx, apps/web/content/articles/how-to-have-productive-one-on-one-meetings.mdx, apps/web/content/articles/how-to-participate-in-meetings-effectively.mdx, apps/web/content/articles/how-to-reduce-meeting-fatigue.mdx, apps/web/content/articles/how-to-transcribe-zoom-calls.mdx, apps/web/content/articles/using-ide-for-writing.mdx, apps/web/content/articles/what-makes-reliable-ai-note-taker.mdx, apps/web/content/articles/why-our-cms-is-github.mdx, apps/web/content/articles/why-we-burned-it-down.mdx
Updated coverImage frontmatter to /api/images/... paths; builders-win-ai-augmented-engineering.mdx added as new article; choosing-a-cms.mdx has publish flag and content restructuring.
Competitor pages icon/frontmatter updates
apps/web/content/vs/aside.mdx, apps/web/content/vs/bear.mdx, apps/web/content/vs/bluedot.mdx, apps/web/content/vs/circleback.mdx, apps/web/content/vs/cluely.mdx, apps/web/content/vs/evernote.mdx, apps/web/content/vs/fathom.mdx, apps/web/content/vs/fellow.mdx, apps/web/content/vs/fireflies.mdx, apps/web/content/vs/gong.mdx, apps/web/content/vs/granola.mdx, apps/web/content/vs/jamie.mdx, apps/web/content/vs/logseq.mdx, apps/web/content/vs/meetgeek.mdx, apps/web/content/vs/notability.mdx, apps/web/content/vs/notion.mdx, apps/web/content/vs/notta.mdx, apps/web/content/vs/obsidian.mdx, apps/web/content/vs/otter.mdx, apps/web/content/vs/read-ai.mdx, apps/web/content/vs/reflect.mdx, apps/web/content/vs/tactiq.mdx, apps/web/content/vs/tldv.mdx
Changed icon frontmatter values from external URLs to /api/images/icons/competitors/... paths.
Docs image migrations
apps/web/content/docs/about/0.hello-world.mdx, apps/web/content/docs/about/1.what-is-hyprnote.mdx, apps/web/content/docs/pro/0.activation.mdx
Converted <img><Image> and updated src values to /api/images/hyprnote/...; added noZoom={true} to some images.
MDX Callout component
apps/web/src/components/mdx/callout.tsx
New React/MDX Callout component added; exposes Callout({ type = "note", children }) and a CALLOUT_STYLES map to control appearance and icon per type.
MDX exports index
apps/web/src/components/mdx/index.ts
Re-exported Callout from ./callout (added to MDX components surface).
Blog route MDX wiring & avatars
apps/web/src/routes/_view/blog/$slug.tsx
Wired MDX component map to include Callout, Image, and img: Image; updated author avatar URLs to /api/images/team/{name}.
Blog index avatars
apps/web/src/routes/_view/blog/index.tsx
Replaced static AUTHOR_AVATARS URLs with /api/images/team/... internal endpoints.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~45 minutes

  • Focus review on:
    • consistency of new /api/images/... path patterns and filenames across content
    • completeness of <img>Image conversions (preserve alt, width/height, other attrs)
    • Callout styling map (CALLOUT_STYLES) and valid Iconify icon keys
    • MDX component mapping in blog/$slug.tsx and any side effects for MDX rendering
    • Author avatar filename consistency between index and slug pages

Possibly related PRs

Suggested reviewers

  • yujonglee

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat/image-component-and-proxy' accurately reflects the main changes: introducing an Image component and implementing a proxy layer for image assets.
Description check ✅ Passed The description is well-aligned with the changeset, covering the key modifications: Image component adoption, Supabase URL transformation to proxy paths, new Callout component, and image path updates across articles.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/image-component-and-proxy

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e647743 and 6fbf652.

📒 Files selected for processing (1)
  • apps/web/content/articles/fireflies-ai-alternatives.mdx (12 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Pages changed - hyprnote-storybook
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: ci
  • GitHub Check: fmt
🔇 Additional comments (2)
apps/web/content/articles/fireflies-ai-alternatives.mdx (2)

7-7: ✅ coverImage front matter properly updated to internal API route.

The coverImage path correctly uses the new /api/images/ internal route convention.


24-24: ✅ All Image components correctly migrated with proper filenames and alt text.

All image references have been consistently updated to:

  • Use the internal /api/images/blog/fireflies-ai-alternatives/ API routes
  • Include descriptive alt attributes for accessibility
  • Match their respective product/section names (the previous critical issue at line 297 has been resolved—now correctly references tactiq.webp for the Tactiq section)

The migration is thorough, with no orphaned or mismatched references detected.

Also applies to: 50-50, 56-56, 62-62, 68-68, 74-74, 102-102, 149-149, 186-186, 225-225, 260-260, 297-297, 334-334, 370-370, 405-405


Comment @coderabbitai help to get the list of available commands and usage tips.

@netlify
Copy link

netlify bot commented Dec 1, 2025

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit 6fbf652
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/692d12c3c39aba0009a22b69
😎 Deploy Preview https://deploy-preview-2030--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@argos-ci
Copy link

argos-ci bot commented Dec 1, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
web (Inspect) ⚠️ Changes detected (Review) 2 changed Dec 1, 2025, 4:02 AM

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (3)
apps/web/content/docs/about/1.what-is-hyprnote.mdx (1)

21-26: Add Image component to MDX components export and provide the referenced image files.

The <Image> component used at lines 21-26 and 31-36 is not exported in the MDXContent components configuration at apps/web/src/routes/_view/docs/-components.tsx (lines 111-127). This will cause a "Image is not defined" runtime error when the page renders. Add Image to the components object:

import { Image } from "@/components/image";

// In ArticleContent:
components={{
  Accordion,
  Card,
  Columns,
  Image,  // Add this
  // ... rest of components
}}

Additionally, the referenced image files (/images/hyprnote-concept-left.jpg and /images/hyprnote-concept-right.jpg) do not exist in the repository. These paths must either be corrected to point to existing images or the image files must be added to public/images/.

apps/web/content/articles/bot-free-ai-meeting-assistants.mdx (1)

7-52: Fix duplicated api/images segments in bot-free article paths

coverImage and the first Hyprnote image use /api/images/api/images/..., unlike the rest of the file, which correctly uses /api/images/blog/.... These two are very likely broken URLs.

Suggested fix:

-coverImage: "/api/images/api/images/blog/bot-free-ai-meeting-assistants/cover.png"
+coverImage: "/api/images/blog/bot-free-ai-meeting-assistants/cover.png"

-<Image src="/api/images/api/images/blog/bot-free-ai-meeting-assistants/hyprnote.webp" alt="Hyprnote"/>
+<Image src="/api/images/blog/bot-free-ai-meeting-assistants/hyprnote.webp" alt="Hyprnote"/>

This matches the pattern used by all other images in the article and in the rest of the PR.

apps/web/content/articles/best-ai-meeting-assistant-for-taking-notes.mdx (1)

7-331: Correct malformed image paths in “best-ai-meeting-assistant” article

Several image URLs here don't match the /api/images/blog/... pattern used elsewhere:

  • coverImage and the first Hyprnote mockup image include "/api/images/api/images/..." (duplicated segment).
  • All later images use ...best-ai-meeting-assistant-for-taking-notes//filename (double slash before the filename).

These are likely to 404 or map to the wrong storage key in your /api/images proxy.

Suggested fixes:

- coverImage: /api/images/api/images/blog/best-ai-meeting-assistant-for-taking-notes//cover.png
+ coverImage: /api/images/blog/best-ai-meeting-assistant-for-taking-notes/cover.png

- <Image src="/api/images/api/images/blog/best-ai-meeting-assistant-for-taking-notes//hyprnote-app-mock.jpg" alt="Hyprnote app mockup"/>
+ <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes/hyprnote-app-mock.jpg" alt="Hyprnote app mockup"/>

- <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes//granola.webp" alt="Granola app"/>
+ <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes/granola.webp" alt="Granola app"/>

- <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes//otter.webp" alt="Otter app"/>
+ <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes/otter.webp" alt="Otter app"/>

- <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes//fireflies.webp" alt="Fireflies"/>
+ <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes/fireflies.webp" alt="Fireflies"/>

- <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes//krisp.webp" alt="Krisp"/>
+ <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes/krisp.webp" alt="Krisp"/>

- <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes//jamie.webp" alt="Jamie"/>
+ <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes/jamie.webp" alt="Jamie"/>

- <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes//avoma.webp" alt="Avoma"/>
+ <Image src="/api/images/blog/best-ai-meeting-assistant-for-taking-notes/avoma.webp" alt="Avoma"/>

Once updated, these will align with the rest of the PR’s /api/images/blog/{slug}/... convention.

🧹 Nitpick comments (11)
apps/web/content/articles/choosing-a-cms.mdx (1)

111-111: Minor style improvements (optional).

Static analysis flagged a few phrases for conciseness and avoiding weak intensifiers. These are optional refinements:

  • Line 111: "a lot of devs" → "many developers" or "numerous developers"
  • Line 148: "lots of content types" → "many content types" or "numerous content types"
  • Line 185: "very good if you want" → Consider a stronger phrasing like "ideal if you need" or "excellent for"

These are low-priority nitpicks but can improve writing clarity.

Also applies to: 148-148, 185-185

apps/web/content/articles/plaud-ai-alternatives.mdx (1)

51-51: Alt text varies in descriptiveness; consider standardizing for accessibility.

Alt text quality is inconsistent across images. Some are concise product names (e.g., line 216: "Nota Memo"), while others provide minimal context. For better accessibility and SEO, consider enriching alt text with brief descriptive context where appropriate.

Example improvement for line 51:

  • Current: "Hyprnote"
  • Suggested: "Hyprnote privacy-focused AI notepad interface"

This is a minor accessibility refinement, not a blocker, but worth considering for consistency with web best practices.

Also applies to: 102-102, 154-154, 216-216, 267-267, 316-316

apps/web/content/articles/zoom-ai-companion-review.mdx (1)

45-45: All alt text attributes should be more descriptive for accessibility.

Several Image components have generic alt text that doesn't adequately describe the image content. This degrades accessibility for screen reader users and search engines.

Examples of current alt text:

  • "How Does Zoom AI Companion Handle Data" (line 45) — describes page context, not image content
  • "Zoom ai companion review" (line 69) — vague
  • "zoom ai companion feedback" (line 78) — vague
  • "is zoom ai multi lingual" (line 104) — question format rather than descriptive

Provide context-specific alt text that describes what each screenshot or image depicts. For example:

- <Image src="/api/images/blog/zoom-ai-companion-review/zoom-alt-2.webp" alt="Zoom ai companion review"/>
+ <Image src="/api/images/blog/zoom-ai-companion-review/zoom-alt-2.webp" alt="Community feedback showing user complaints about Zoom AI Companion summary accuracy issues"/>

- <Image src="/api/images/blog/zoom-ai-companion-review/zoom-alt-6.webp" alt="is zoom ai multi lingual"/>
+ <Image src="/api/images/blog/zoom-ai-companion-review/zoom-alt-6.webp" alt="User feedback highlighting multi-language transcription quality degradation"/>

Also applies to: 69-69, 78-78, 87-87, 94-94, 104-104, 111-111, 118-118, 127-127, 143-143, 153-153, 165-165, 179-179

apps/web/content/articles/meeting-preparation-checklist.mdx (1)

27-27: Add width and height attributes to Image components to prevent layout shifts.

Missing width and height attributes on Image components can cause Cumulative Layout Shift (CLS) issues. The width and height attributes are critical for avoiding layout shifts during loading, which can result in a poor user experience. When working with remote images, width and height must be manually defined because Next.js can't access remote files during the build process. Explicitly defining the width and height helps Next.js know how much space to reserve for the image, which prevents layout shifts from occurring when the image loads.

Also applies to: 54-54, 122-122, 145-145

apps/web/content/articles/otter-ai-review.mdx (1)

64-64: Replace generic "Source" alt text with descriptive labels.

Several images use generic alt="Source" labels, which provides no context to screen readers or search engines. Replace these with descriptive text that explains what each screenshot depicts (e.g., "Otter security concerns lawsuit details" for line 64, "User review highlighting transcription accuracy concerns" for line 150).

Also applies to: 84-84, 136-136, 146-146, 150-150, 154-154, 159-159, 163-163

apps/web/content/articles/google-gemini-meeting-notes.mdx (1)

55-55: Improve alt text for accessibility.

The alt text for these images ("Gemini" and "Hyprnote") is too generic and doesn't describe the image content. More descriptive alt text improves accessibility for screen reader users.

Consider updating alt text to be more descriptive:

-<Image src="/api/images/blog/google-gemini-meeting-notes/gemini-1.webp" alt="Gemini"/>
+<Image src="/api/images/blog/google-gemini-meeting-notes/gemini-1.webp" alt="Manual approach to using Gemini for meeting note-taking"/>

-<Image src="/api/images/blog/google-gemini-meeting-notes/gemini-2.webp" alt="Hyprnote"/>
+<Image src="/api/images/blog/google-gemini-meeting-notes/gemini-2.webp" alt="Hyprnote interface for taking meeting notes"/>

Also applies to: 117-117

apps/web/content/articles/builders-win-ai-augmented-engineering.mdx (1)

37-37: Repetitive sentence structure reduces readability.

Three successive sentences begin with "Every," which impacts flow. Consider rewording one or more to vary sentence openers (e.g., "They write more. Shipping increases. Fewer bugs occur."). This aligns with style guidance from static analysis.

apps/web/src/routes/_view/blog/index.tsx (1)

9-13: Avatar sources now correctly proxied via /api/images

The AUTHOR_AVATARS map now points at /api/images/team/john.png, /api/images/team/harshika.jpeg, and /api/images/team/yujong.png, which aligns with the new internal image proxy scheme and removes direct storage URLs.

If you later want full consistency with the new image pipeline (caching, optimization, etc.), consider swapping the avatar <img> tags in this file to reuse the shared Image component.

apps/web/content/articles/chatgpt-for-meeting-notes.mdx (1)

10-10: Record mode screenshots wired to <Image> with consistent alt text

Both initial ChatGPT Record Mode screenshots correctly use <Image> and the /api/images/blog/chatgpt-for-meeting-notes/chatgpt-*.webp paths. Alt text is meaningful; if you ever want to distinguish the two views more precisely, you could tweak the second alt, but it’s not required.

Also applies to: 25-25

apps/web/src/components/mdx/callout.tsx (1)

33-58: Consider adding a runtime fallback for type (and optional a11y role)

Right now, an invalid type coming from MDX would make style undefined and throw at style.container / style.icon. A small runtime guard would make this more robust:

-  const style = CALLOUT_STYLES[type];
+  const style = CALLOUT_STYLES[type] ?? CALLOUT_STYLES.note;

Optionally, you could also differentiate screen-reader semantics:

-    <div
-      className={cn([
+    <div
+      role={type === "warning" || type === "danger" ? "alert" : "note"}
+      className={cn([
         "not-prose my-6 p-4 rounded-sm border flex gap-3",
-        ...style.container,
+        ...style.container,
       ])}

Both are non-breaking but make the component safer and a bit more accessible.

Please verify that this change still type-checks cleanly with your current React/TypeScript and MDX compilation setup.

apps/web/content/articles/is-otter-ai-safe.mdx (1)

7-7: Cover image now uses the internal image proxy

coverImage is correctly updated to /api/images/blog/is-otter-ai-safe/cover.png, aligned with the rest of the PR’s image handling. Unrelated, but while you’re here, line 20’s link text has a small typo (“Alterntives” → “Alternatives”) if you want to clean that up.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7747cb6 and e647743.

📒 Files selected for processing (71)
  • apps/web/content/articles/ai-meeting-summary-tools.mdx (11 hunks)
  • apps/web/content/articles/best-ai-meeting-assistant-for-taking-notes.mdx (8 hunks)
  • apps/web/content/articles/best-ai-notetaker-for-in-person-meetings.mdx (8 hunks)
  • apps/web/content/articles/best-ai-notetaker-for-microsoft-teams.mdx (9 hunks)
  • apps/web/content/articles/best-ai-notetaker-for-zoom.mdx (11 hunks)
  • apps/web/content/articles/best-ai-notetakers-google-meet.mdx (8 hunks)
  • apps/web/content/articles/bot-free-ai-meeting-assistants.mdx (13 hunks)
  • apps/web/content/articles/builders-win-ai-augmented-engineering.mdx (1 hunks)
  • apps/web/content/articles/can-you-transcribe-meetings-without-sending-data-to-cloud.mdx (2 hunks)
  • apps/web/content/articles/chatgpt-for-meeting-notes.mdx (5 hunks)
  • apps/web/content/articles/choosing-a-cms.mdx (8 hunks)
  • apps/web/content/articles/enterprise-ai-notetaking-tools.mdx (8 hunks)
  • apps/web/content/articles/fathom-ai-alternatives.mdx (6 hunks)
  • apps/web/content/articles/fireflies-ai-alternatives.mdx (12 hunks)
  • apps/web/content/articles/free-ai-notetakers.mdx (19 hunks)
  • apps/web/content/articles/free-transcription-software.mdx (11 hunks)
  • apps/web/content/articles/google-gemini-meeting-notes.mdx (3 hunks)
  • apps/web/content/articles/granola-ai-alternatives.mdx (9 hunks)
  • apps/web/content/articles/how-to-have-productive-one-on-one-meetings.mdx (1 hunks)
  • apps/web/content/articles/how-to-participate-in-meetings-effectively.mdx (1 hunks)
  • apps/web/content/articles/how-to-reduce-meeting-fatigue.mdx (1 hunks)
  • apps/web/content/articles/how-to-transcribe-zoom-calls.mdx (7 hunks)
  • apps/web/content/articles/is-ai-notetaking-legal.mdx (2 hunks)
  • apps/web/content/articles/is-fireflies-ai-safe.mdx (6 hunks)
  • apps/web/content/articles/is-otter-ai-safe.mdx (6 hunks)
  • apps/web/content/articles/local-ai-privacy-tools.mdx (2 hunks)
  • apps/web/content/articles/meeting-minutes-software.mdx (8 hunks)
  • apps/web/content/articles/meeting-preparation-checklist.mdx (5 hunks)
  • apps/web/content/articles/open-source-meeting-transcription-software.mdx (4 hunks)
  • apps/web/content/articles/otter-ai-alternatives.mdx (17 hunks)
  • apps/web/content/articles/otter-ai-review.mdx (7 hunks)
  • apps/web/content/articles/plaud-ai-alternatives.mdx (7 hunks)
  • apps/web/content/articles/post-yc-slump.mdx (1 hunks)
  • apps/web/content/articles/sales-ai-note-takers.mdx (6 hunks)
  • apps/web/content/articles/see-zoom-meeting-history.mdx (5 hunks)
  • apps/web/content/articles/tldv-review.mdx (7 hunks)
  • apps/web/content/articles/using-ide-for-writing.mdx (1 hunks)
  • apps/web/content/articles/what-makes-reliable-ai-note-taker.mdx (1 hunks)
  • apps/web/content/articles/why-our-cms-is-github.mdx (1 hunks)
  • apps/web/content/articles/why-we-burned-it-down.mdx (4 hunks)
  • apps/web/content/articles/zoom-ai-companion-review.mdx (11 hunks)
  • apps/web/content/docs/about/0.hello-world.mdx (1 hunks)
  • apps/web/content/docs/about/1.what-is-hyprnote.mdx (2 hunks)
  • apps/web/content/docs/pro/0.activation.mdx (2 hunks)
  • apps/web/content/vs/aside.mdx (1 hunks)
  • apps/web/content/vs/bear.mdx (1 hunks)
  • apps/web/content/vs/bluedot.mdx (1 hunks)
  • apps/web/content/vs/circleback.mdx (1 hunks)
  • apps/web/content/vs/cluely.mdx (1 hunks)
  • apps/web/content/vs/evernote.mdx (1 hunks)
  • apps/web/content/vs/fathom.mdx (1 hunks)
  • apps/web/content/vs/fellow.mdx (1 hunks)
  • apps/web/content/vs/fireflies.mdx (1 hunks)
  • apps/web/content/vs/gong.mdx (1 hunks)
  • apps/web/content/vs/granola.mdx (1 hunks)
  • apps/web/content/vs/jamie.mdx (1 hunks)
  • apps/web/content/vs/logseq.mdx (1 hunks)
  • apps/web/content/vs/meetgeek.mdx (1 hunks)
  • apps/web/content/vs/notability.mdx (1 hunks)
  • apps/web/content/vs/notion.mdx (1 hunks)
  • apps/web/content/vs/notta.mdx (1 hunks)
  • apps/web/content/vs/obsidian.mdx (1 hunks)
  • apps/web/content/vs/otter.mdx (1 hunks)
  • apps/web/content/vs/read-ai.mdx (1 hunks)
  • apps/web/content/vs/reflect.mdx (1 hunks)
  • apps/web/content/vs/tactiq.mdx (1 hunks)
  • apps/web/content/vs/tldv.mdx (1 hunks)
  • apps/web/src/components/mdx/callout.tsx (1 hunks)
  • apps/web/src/components/mdx/index.ts (1 hunks)
  • apps/web/src/routes/_view/blog/$slug.tsx (2 hunks)
  • apps/web/src/routes/_view/blog/index.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Agent implementations should use TypeScript and follow the established architectural patterns defined in the agent framework
Agent communication should use defined message protocols and interfaces

Files:

  • apps/web/src/components/mdx/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/components/mdx/index.ts
  • apps/web/src/routes/_view/blog/index.tsx
  • apps/web/src/components/mdx/callout.tsx
  • apps/web/src/routes/_view/blog/$slug.tsx
🧬 Code graph analysis (2)
apps/web/src/components/mdx/callout.tsx (2)
apps/web/src/components/mdx/index.ts (1)
  • Callout (1-1)
packages/utils/src/cn.ts (1)
  • cn (20-22)
apps/web/src/routes/_view/blog/$slug.tsx (1)
apps/web/src/components/image.tsx (1)
  • Image (4-24)
🪛 LanguageTool
apps/web/content/articles/builders-win-ai-augmented-engineering.mdx

[style] ~37-~37: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ecision becomes context we can revisit. Every idea gets distilled and carried forward...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

apps/web/content/articles/choosing-a-cms.mdx

[style] ~111-~111: Consider using a synonym to be more concise.
Context: ...ace include TinaCMS, Decap, etc., which a lot of devs compare as “Git-based CMS for Reac...

(A_LOT_OF)


[style] ~148-~148: Consider using a synonym to be more concise.
Context: ...great when you have multiple frontends, lots of content types, and non-technical editor...

(A_LOT_OF)


[style] ~185-~185: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...Book](https://gitbook.com/docs) It’s very good if you want: - a hosted, beautiful doc...

(EN_WEAK_ADJECTIVE)


[style] ~185-~185: This phrasing can be overused. Try elevating your writing with a more formal alternative.
Context: ...s://gitbook.com/docs) It’s very good if you want: - a hosted, beautiful docs site - s...

(IF_YOU_WANT)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: ci
  • GitHub Check: fmt
🔇 Additional comments (92)
apps/web/content/articles/how-to-reduce-meeting-fatigue.mdx (1)

7-7: Verify that the /api/images proxy endpoint is correctly configured to resolve this path.

The front matter change from an absolute Supabase URL to a relative API path aligns with the PR objectives. The path convention follows the expected pattern: /api/images/blog/{article-slug}/{image-name}.

Ensure that the /api/images endpoint is properly configured in the backend to:

  • Intercept requests to this path
  • Map the path to the correct Supabase storage location
  • Return the image with appropriate headers (content-type, caching, etc.)

If the proxy endpoint isn't yet wired, requests to the cover image will fail and break article rendering.

apps/web/content/vs/logseq.mdx (1)

3-3: Verify the /api/images proxy endpoint is properly configured and accessible.

The icon URL has been migrated to the internal API route following the PR's broader migration pattern. Ensure that the proxy endpoint correctly resolves and returns the image for this path.

To verify, please confirm:

  1. The /api/images/icons/competitors/logseq.png endpoint is properly implemented in the application
  2. The image asset is accessible via the proxy and returns a 200 status
  3. The original image source is correctly mapped in the proxy implementation

If needed, you can verify this manually by testing the endpoint in a browser or via curl once the changes are deployed to a staging environment.

apps/web/content/articles/sales-ai-note-takers.mdx (2)

8-8: Front matter migration looks good; verify API route exists.

The coverImage path update from Supabase URL to local API proxy is clean. However, ensure the /api/images/blog/sales-ai-note-takers/cover.png endpoint is wired up and returns the image with proper cache headers.


35-35: Verify Image component accepts missing width/height props and confirm API endpoint.

All five inline Image components use consistent paths and include descriptive alt text (good for accessibility). However, the components lack explicit width and height props. If you're using the Next.js <Image> component directly, this typically causes:

  • Cumulative Layout Shift (CLS) without explicit dimensions
  • Warnings during build/runtime
  • Unoptimized responsive image loading

Depending on your Image component definition, this may be:

  • ✓ Handled correctly if it's a custom MDX wrapper with CSS-based sizing or defaults
  • ✗ A missing required prop if it's the standard Next.js Image component

Additionally, the /api/images proxy route must exist, be performant, and serve images with appropriate cache headers. Direct Supabase CDN access typically has lower latency.

Please confirm:

  1. Image component source: Is <Image> a custom wrapper or the Next.js Image component? If the latter, do width/height props need to be added?
  2. API endpoint: Does /api/images/blog/sales-ai-note-takers/... exist and serve images correctly?

To verify, search the codebase for the Image component definition and the /api/images route implementation.

Also applies to: 78-78, 127-127, 172-172, 221-221

apps/web/content/articles/choosing-a-cms.mdx (4)

7-7: ⚠️ Verify: Article marked as unpublished—is this intentional?

Line 7 changes published from true to false, which will make this article unavailable to readers. Since the PR objective is to migrate images and add components (not remove content), this appears to be an unintended change. Please confirm:

  • Should this article remain published (true)?
  • Is this a deliberate draft/archive state?

90-90: Citation markers in modified lines need clarification or removal.

The modified lines contain inline citations formatted as [oai_citation:X‡Name](URL). These don't render as standard markdown links and appear to be auto-inserted metadata or AI-generated artifacts (e.g., line 90: [oai_citation:0‡Next.js](https://nextjs.org/...)).

Please clarify:

  • Are these intended as structured citations?
  • Should they be removed as build/generation artifacts?
  • If they should be citations, they need proper markdown formatting for MDX rendering.

This pattern affects ~15+ modified lines throughout the file.

Also applies to: 109-109, 111-111, 138-138, 144-146, 152-152, 155-157, 163-163, 183-183, 189-189, 198-198, 225-225, 304-304, 306-306, 308-308


212-220: New summary table is a solid addition.

The "Summary: The Four Buckets at a Glance" table (lines 212–220) provides excellent quick reference, clearly maps trade-offs, and improves article scannability. Good structural addition.


1-320: PR scope mismatch: No image component replacements visible in this file.

Per the PR objective, this migration should replace inline <img> tags with a React <Image> component. However, this file shows no such conversions—only content edits (citation link updates, table addition, prose refinement).

Verify:

  • Did this article originally contain inline images that should have been migrated to the <Image> component?
  • If no images were present, that's fine—but ensure consistency across other files listed in the PR scope (70+ content files mentioned).
  • Confirm whether the Callout MDX component should be integrated into this article (mentioned in PR summary but not visible here).
apps/web/content/articles/plaud-ai-alternatives.mdx (1)

8-8: Verify Image component import and proxy endpoint availability.

The migration from external URLs to /api/images proxy paths looks systematic and consistent across all instances (lines 8, 51, 102, 154, 216, 267, 316). However, confirm:

  1. The Image component is properly imported in this MDX file's rendering context.
  2. The /api/images/blog/plaud-ai-alternatives/* endpoints exist and correctly resolve the referenced images.
  3. The Image component definition supports the src and alt props as used here.
apps/web/content/vs/reflect.mdx (1)

3-3: Verification complete: /api/images endpoint and path mapping are properly implemented.

The endpoint at apps/web/src/routes/api/images.$.ts correctly proxies requests to Supabase storage with proper security measures:

  • Path sanitization prevents directory traversal attacks
  • Error handling returns appropriate status codes (404 for missing assets, 502 for upstream errors)
  • Content-Type and cache headers are preserved from upstream responses
  • All 24 comparison files consistently use the /api/images/icons/competitors/{name} pattern with no remaining external URLs

The migration is complete and functioning as intended.

apps/web/content/vs/bluedot.mdx (1)

3-3: No action needed — the /api/images proxy is properly implemented and the icon path is correctly configured.

The API route handler (apps/web/src/routes/api/images.$.ts) proxies requests to Supabase storage, with proper path sanitization and error handling. The icon path /api/images/icons/competitors/bluedot.jpg follows the same pattern used throughout the codebase in all other comparison files (fellow, reflect, tldv, etc.). The migration is safe.

Likely an incorrect or invalid review comment.

apps/web/content/articles/how-to-have-productive-one-on-one-meetings.mdx (2)

1-211: No action needed—this article contains no inline images to migrate.

The file genuinely has no <img> or <Image> components in its body content. Other articles in the same directory show the expected <Image> component usage pattern, confirming the PR updates are active. This file's absence of inline images is legitimate and requires no changes.


8-8: No action required—the API route and image pattern are already established.

The /api/images/blog/ prefix is already implemented and used consistently across the codebase. The route handler exists at apps/web/src/routes/api/images.$.ts, and this coverImage path follows the established pattern used throughout blog articles. The change is correct as-is.

apps/web/content/articles/can-you-transcribe-meetings-without-sending-data-to-cloud.mdx (2)

7-7: No action needed. The /api/images/* endpoint is properly configured in apps/web/src/routes/api/images.$.ts with:

  • URL transformation logic that maps API paths to Supabase storage (line 44)
  • Appropriate caching headers with 1-year immutable cache by default (line 65)
  • Proper content-type handling forwarded from upstream (line 60)
  • Path sanitization for security

52-52: No action needed. The <Image> component is correctly available in MDX scope through the MDXContent components prop in the blog route (apps/web/src/routes/_view/blog/$slug.tsx, line 329), which is the standard MDX pattern for component customization. The component from @/components/image properly accepts the src and alt props being used at line 52.

apps/web/content/vs/fellow.mdx (1)

3-3: No action required – icon path is correctly configured and consistent with the established pattern.

The /api/images route handler is properly implemented with path sanitization, error handling, and caching headers. The icon path follows the identical pattern used across all 23+ competitor files in apps/web/content/vs/, confirming this change is part of the completed systematic migration to the internal Supabase proxy route.

apps/web/content/vs/fathom.mdx (1)

3-3: The /api/images endpoint is properly implemented and handles the icon proxy paths correctly. The path /api/images/icons/competitors/fathom.png follows the established pattern used consistently across all comparison files and is supported by the API route's path sanitization logic.

apps/web/content/articles/best-ai-notetakers-google-meet.mdx (3)

7-7: The /api/images proxy route is properly configured and operational. The route handler at apps/web/src/routes/api/images.$.ts implements a secure proxy that:

  • Sanitizes paths to prevent directory traversal attacks
  • Proxies requests to Supabase Storage
  • Properly handles Content-Type and Cache-Control headers
  • Returns appropriate HTTP status codes (404, 502)

Image files are served from Supabase, not stored locally, so the paths will resolve correctly at runtime. No action needed.


42-42: No action required. The Image component is properly exported and integrated into the MDX rendering pipeline at apps/web/src/routes/_view/blog/$slug.tsx. The /api/images route is configured to proxy images from Supabase storage, so the image paths will resolve correctly.


7-7: The coverImage frontmatter is correctly processed in the blog rendering pipeline. The CoverImage component in apps/web/src/routes/_view/blog/$slug.tsx retrieves the frontmatter field and passes it to the Image component, which uses @unpic/react for image optimization and delivery. The /api/images/... path format is handled by Unpic's image proxy system automatically. No further action needed.

apps/web/content/articles/fireflies-ai-alternatives.mdx (1)

1-405: Verify that all 15 referenced images exist in Supabase storage.

The Image component is properly registered and wired into the MDX rendering pipeline, with no remaining external URLs in the article. However, the /api/images/ endpoint is a Supabase proxy handler, so all images must be uploaded to the Supabase bucket at public_images/blog/fireflies-ai-alternatives/ with the exact filenames referenced: cover.png, fireflies-0.webp through fireflies-5.webp, hyprnote.webp (used twice), avoma.webp, otter.webp, meetgeek.webp, read-ai.webp, sembly-ai.webp, fathom.webp, and sonnet.webp.

apps/web/content/articles/how-to-transcribe-zoom-calls.mdx (2)

7-7: Frontmatter coverImage path correctly updated to proxy endpoint.

The coverImage path has been successfully migrated to the /api/images proxy pattern, consistent with the PR objectives.


30-30: Image components properly implemented with descriptive alt text.

All <Image> components are correctly self-closing with descriptive alt attributes, following accessibility best practices. The /api/images/blog/how-to-transcribe-zoom-calls/ proxy paths are applied consistently across all image references. The Image component is properly available in the MDX rendering context via explicit component passing to MDXContent in the blog route.

apps/web/content/articles/zoom-ai-companion-review.mdx (1)

7-7: All integration prerequisites are verified and working correctly. The Image component is properly configured using @unpic/react with responsive layout handling, the MDX compilation is set up through @content-collections/mdx, the API endpoint at /api/images/$ is fully implemented with path sanitization and proper cache headers (1-year immutable caching), and blog images are stored in the Supabase bucket with the endpoint proxying requests appropriately. No gaps or issues identified in the implementation.

apps/web/content/articles/post-yc-slump.mdx (2)

8-8: URL path transformation is consistent.

The coverImage front matter has been updated to use the internal proxy URL pattern (/api/images/blog/post-yc-slump/cover.png). This aligns with the body content changes.


13-13: All verification points confirmed—no action required.

The <Image> component is properly integrated and the /api/images proxy endpoint is fully configured. The component doesn't require explicit imports in the MDX file because it's registered via the components prop in ArticleContent (blog/$slug.tsx: components={{ ..., Image, img: Image, ... }}), which makes it auto-available in the MDX context through content-collections. The endpoint proxies to Supabase with proper path sanitization and cache headers. Width and height props are optional—the Unpic-based Image component handles responsive sizing automatically with layout="constrained" by default, so their absence doesn't impact functionality.

apps/web/content/articles/meeting-preparation-checklist.mdx (1)

8-8: All image migration requirements are properly implemented and verified.

The codebase confirms:

  1. Image component integration: The Image component is properly imported in the blog route (apps/web/src/routes/_view/blog/$slug.tsx line 11) and available for MDX rendering via the content-collections pipeline.

  2. API endpoint functionality: The /api/images proxy endpoint exists (apps/web/src/routes/api/images.$.ts) with proper path sanitization, error handling, and content-type detection for all image formats (.png, .webp, etc.).

  3. Complete migration: All 313 /api/images references in 153 content files have been successfully migrated with zero external URLs remaining — full migration verified.

  4. Supabase transformation: The proxy correctly transforms internal /api/images/... URLs to the Supabase storage endpoint (https://ijoptyyjrfqwaqhyxkxj.supabase.co/storage/v1/object/public/public_images).

All five specified lines (8, 27, 54, 122, 145) in the file properly use /api/images URLs with correct format handling (.png and .webp).

apps/web/content/articles/otter-ai-review.mdx (4)

7-7: Verify the cover image API route serves the correct file.

The migration to internal API route follows a consistent pattern, but ensure the endpoint /api/images/blog/otter-ai-review/cover.png returns the expected image.


48-48: No issues found. The CtaCard component is properly imported in the blog route (/src/routes/_view/blog/$slug.tsx line 10) and correctly registered in the MDX components configuration (line 328). All three instances will render with appropriate defaults.

Likely an incorrect or invalid review comment.


1-225: All systems verified and functional—no action required.

The Image and CtaCard components are properly registered in the blog article route at runtime. The API endpoint proxies to Supabase storage with path sanitization. Image files are correctly designed to be stored in Supabase CDN (not the local repository) and served through the /api/images/ endpoint. The article will render without issues.


24-24: No action needed. The Image component is properly registered in the MDX scope (imported at line 11 of apps/web/src/routes/_view/blog/$slug.tsx and passed to MDXContent at line 329). The component uses @unpic/react, which is a responsive image library that does not require explicit width and height props—it handles responsive sizing automatically with the "constrained" layout as the default. All Image instances in the MDX file will render correctly without additional width/height attributes.

Likely an incorrect or invalid review comment.

apps/web/content/articles/why-our-cms-is-github.mdx (1)

7-7: Metadata path updated consistently with PR pattern.

The frontmatter coverImage has been migrated to an internal API route. Ensure the image file exists at /api/images/blog/why-our-cms-is-github/cover.png and that the API endpoint is implemented to serve it.

apps/web/content/docs/pro/0.activation.mdx (1)

10-14: Verify Image component is wired into MDX rendering context.

The <Image> component is being used with src, alt, and title props. Ensure:

  1. The Image component is exported from apps/web/src/components/mdx/index.ts (or equivalent)
  2. It's registered in the MDX components map for this doc route
  3. Image files exist at the referenced paths (/api/images/docs/pro/activation-1.png and activation-2.png)

Also applies to: 24-28

apps/web/content/articles/what-makes-reliable-ai-note-taker.mdx (1)

8-8: Frontmatter metadata updated with API route path.

Ensure the cover image exists at /api/images/blog/what-makes-reliable-ai-note-taker/cover.png and the API endpoint serves it.

apps/web/content/vs/meetgeek.mdx (1)

3-3: Icon path updated to internal API route.

Verify the icon file exists at /api/images/icons/competitors/meetgeek.png.

apps/web/content/vs/evernote.mdx (1)

3-3: Icon path with .jpg extension.

Verify the icon file exists at /api/images/icons/competitors/evernote.jpg. Note the .jpg extension differs from other competitor icons.

apps/web/content/vs/notion.mdx (1)

3-3: Icon path updated to internal API route.

Verify the icon file exists at /api/images/icons/competitors/notion.png.

apps/web/content/vs/otter.mdx (1)

3-3: Icon path with .jpeg extension.

Verify the icon file exists at /api/images/icons/competitors/otter.jpeg. Note the .jpeg extension differs from other competitor icons (.png, .jpg).

apps/web/content/articles/how-to-participate-in-meetings-effectively.mdx (1)

8-8: Frontmatter metadata updated with blog API route path.

Ensure the cover image exists at /api/images/blog/how-to-participate-in-meetings-effectively/cover.png.

apps/web/content/vs/notability.mdx (1)

3-3: Verify image API endpoint resolves all icon paths.

The icon path migration from external Supabase URLs to internal /api/images paths requires that the backend image proxy is implemented and correctly maps all paths. Please confirm the /api/images/icons/competitors/notability.png endpoint resolves without 404s.

apps/web/content/articles/using-ide-for-writing.mdx (1)

8-8: Path migration looks good; verify backend routing.

The coverImage path follows the consistent /api/images/blog/{article-slug}/ pattern established across the PR. Ensure the /api/images/blog/using-ide-for-writing/cover.png endpoint is wired correctly in the image API.

apps/web/content/vs/gong.mdx (1)

3-3: Verify mixed icon file extensions map to correct originals.

Icon paths use varied extensions (.png, .jpeg, .jpg). Ensure the path mapping in /api/images/icons/competitors/gong.jpeg correctly routes to the original Supabase file without extension mismatches.

apps/web/content/articles/is-ai-notetaking-legal.mdx (2)

7-7: Verify coverImage path and Image component integration.

The coverImage migration pairs with in-article use of the <Image> component (line 163). Confirm that:

  1. The Image component is properly exported from apps/web/src/components/mdx/index.ts
  2. The /api/images/blog/is-ai-notetaking-legal/cover.png endpoint resolves

163-163: Verify Image component receives correct props and renders.

The <Image> component is now used with src and alt props. Confirm the component signature accepts these props and doesn't require additional required props (e.g., width, height for Next.js Image component).

apps/web/content/vs/tldv.mdx (1)

3-3: Path follows established pattern.

Consistent with other competitor icon migrations to /api/images/icons/competitors/. Ensure the backend routes this path correctly.

apps/web/content/vs/bear.mdx (1)

3-3: Icon path follows established convention.

Migrates to /api/images/icons/competitors/bear.png following the PR's consistent path structure.

apps/web/content/vs/circleback.mdx (1)

3-3: Icon path follows established convention.

Migrates to /api/images/icons/competitors/circleback.jpg within the established PR pattern.

apps/web/content/vs/tactiq.mdx (2)

3-3: Icon path follows established convention.

Migrates to /api/images/icons/competitors/tactiq.png consistent with the PR-wide path structure.


1-7: Verify comprehensive image API implementation for 70+ file migration.

This PR migrates icons and images across 70+ content files to internal /api/images routes. Before merging, confirm:

  1. Image API endpoint implemented at apps/web/src/routes/api/images (or equivalent) that:

    • Accepts paths like /icons/competitors/{name}.{ext} and /blog/{article-slug}/{image-name}.{ext}
    • Routes requests to the correct Supabase or local storage location
    • Handles mixed file extensions (.png, .jpeg, .jpg, .webp) without errors
  2. All image paths exist — Run a validation check across all modified files to confirm no 404s will occur

  3. Image component exports — Verify apps/web/src/components/mdx/index.ts exports the Image component and it's registered with the MDX renderer in blog routes

apps/web/content/articles/fathom-ai-alternatives.mdx (1)

7-7: Image paths and component usage look consistent.

All image references have been updated to use the /api/images/ internal proxy paths and the <Image> MDX component is correctly applied with descriptive alt text. Path naming is consistent with the blog slug convention.

Please verify that the Image component is properly available in the MDX rendering context for blog articles and that the image files exist at all specified paths.

Also applies to: 49-49, 93-93, 136-136, 179-179, 226-226

apps/web/content/vs/read-ai.mdx (1)

3-3: Icon path update is consistent with pattern.

The icon path has been successfully migrated to the internal API route following the established /api/images/icons/competitors/{name}.{ext} pattern.

apps/web/content/vs/aside.mdx (1)

3-3: Icon path correctly migrated to internal API route.

The icon path follows the established pattern for competitor icons. Note that this file uses .jpg while others use .webp; verify this is intentional and that source assets are correctly named.

apps/web/content/articles/see-zoom-meeting-history.mdx (1)

8-8: Image migration is comprehensive and well-structured.

All seven images have been consistently migrated to the internal API proxy with appropriate alt text. The path naming follows the established convention and alt descriptions are descriptive and helpful.

Verify that the Image component properly handles both .png and .webp formats, and confirm that all image files exist at the specified paths.

Also applies to: 19-19, 85-85, 95-95, 114-114, 118-118, 122-122, 128-128

apps/web/content/vs/granola.mdx (1)

3-3: Competitor icon path successfully updated to internal route.

The icon path has been migrated to the /api/images/icons/competitors/ internal route following the established pattern.

apps/web/content/vs/fireflies.mdx (1)

3-3: Competitor icon path migrated to internal route.

The icon path follows the established /api/images/icons/competitors/ pattern. Note the file uses .jpeg extension; verify the source file is named correctly.

apps/web/content/vs/jamie.mdx (1)

3-3: Competitor icon path migrated successfully.

The icon path has been updated to the internal /api/images/icons/competitors/ route following the established pattern.

apps/web/content/articles/free-transcription-software.mdx (1)

8-8: Image migration appears consistent throughout file.

All 12 image paths successfully migrated to /api/images/blog/free-transcription-software/{image} pattern with Image component replacements. Frontmatter coverImage and in-content images maintain alt text and semantic structure.

Also applies to: 77-77, 98-98, 110-110, 135-135, 143-143, 164-164, 209-209, 232-232, 244-244, 269-269

apps/web/content/docs/about/0.hello-world.mdx (1)

25-37: Theme-aware image rendering preserved correctly.

The conditional rendering logic for dark/light mode signatures is maintained—block dark:hidden and hidden dark:block className patterns continue to work as expected with Image components.

apps/web/content/articles/builders-win-ai-augmented-engineering.mdx (2)

1-8: Verify article publication status before merge.

This new article is marked published: false (Line 7). Confirm whether this should remain unpublished or be toggled to published: true for the release.


43-45: Callout component usage—verify implementation is exported.

The Callout component is used with type="note" but the component definition and its MDX export are not visible in the provided code. Per the PR objectives, a new Callout component was introduced (apps/web/src/components/mdx/callout.tsx) and re-exported. Ensure:

  1. The Callout component is properly exported from apps/web/src/components/mdx/index.ts
  2. The blog route rendering integration (mentioned in AI summary) properly surfaces Callout to MDX consumers
  3. The component accepts and renders the type prop correctly
apps/web/content/articles/why-we-burned-it-down.mdx (1)

8-8: Image migration with explicit sizing for avatars and signature.

All images migrated to /api/images/ paths. Team avatar images (lines 197–215) and signature (lines 222–228) have explicit width and height attributes, which is appropriate for fixed-size UI elements. Object-cover classes correctly handle aspect ratio for circular avatars.

Also applies to: 197-228

apps/web/content/articles/local-ai-privacy-tools.mdx (1)

7-7: Image paths and component usage are correct.

Both coverImage (line 7) and in-content image (line 60) successfully migrated to /api/images/blog/local-ai-privacy-tools/ paths with proper Image component replacements.

Also applies to: 60-60

apps/web/content/articles/enterprise-ai-notetaking-tools.mdx (1)

8-8: Comprehensive image migration across seven product comparisons.

All seven enterprise tool images (enterprise-1.webp through enterprise-7.webp) successfully migrated from external URLs to /api/images/blog/enterprise-ai-notetaking-tools/ paths. Alt text is descriptive and aids accessibility.

Also applies to: 42-42, 56-56, 78-78, 108-108, 139-139, 174-174, 209-209

apps/web/content/vs/notta.mdx (1)

3-3: Icon path migrated to API endpoint.

Icon frontmatter field updated to /api/images/icons/competitors/notta.png. Verify this endpoint serves icon assets with correct MIME types and cache headers for static assets.

apps/web/content/vs/cluely.mdx (1)

3-3: Icon path migrated to API endpoint.

Icon frontmatter updated to /api/images/icons/competitors/cluely.jpg. Ensure the /api/images endpoint handles both .png and .jpg extensions consistently with proper Content-Type headers.

apps/web/content/vs/obsidian.mdx (1)

3-3: Icon path normalization looks correct

icon now points at /api/images/icons/competitors/obsidian.jpg, consistent with the new image proxy pattern.

apps/web/content/articles/ai-meeting-summary-tools.mdx (1)

7-395: Image proxy + <Image> usage look consistent

All image references (cover and inline) now use /api/images/blog/ai-meeting-summary-tools/* with the new <Image /> component and preserved alt text. No obvious path typos or inconsistencies.

apps/web/content/articles/best-ai-notetaker-for-microsoft-teams.mdx (1)

7-278: Teams notetaker article image paths are clean

Cover and inline images all use /api/images/blog/best-ai-notetaker-for-microsoft-teams/* with <Image />, and alt text is preserved. Looks good.

apps/web/src/components/mdx/index.ts (1)

1-3: Callout re-export wired correctly

Adding export { Callout } from "./callout"; cleanly extends the MDX components surface alongside Mermaid and Tweet.

apps/web/content/articles/tldv-review.mdx (1)

8-209: tl;dv review images correctly migrated

All images (cover and inline) now use /api/images/blog/tldv-review/* with <Image />, and alt text remains descriptive. No issues spotted.

apps/web/src/routes/_view/blog/$slug.tsx (3)

12-12: LGTM: Callout component integration.

The Callout component is properly imported and wired into MDX rendering, enabling rich content blocks in blog articles.

Also applies to: 327-327


329-330: LGTM: Image component wiring for MDX.

The dual mapping (Image and img: Image) ensures both explicit <Image> components and standard Markdown ![](...) syntax render using the custom Image component. This provides consistent image handling across MDX content.


15-17: The API route implementation is complete and correctly proxies to Supabase storage.

The /api/images/$ route handler is properly implemented to fetch images from the Supabase storage endpoint. The avatar paths are correctly formatted for this proxy pattern. Verify that the corresponding image files exist in Supabase storage (team/john.png, team/harshika.jpeg, team/yujong.png) before deploying, as file existence cannot be confirmed through code review alone.

apps/web/content/articles/best-ai-notetaker-for-in-person-meetings.mdx (2)

7-7: LGTM: Image migration to internal API paths.

The systematic migration of image assets from external Supabase storage to internal /api/images/blog/... paths is clean and consistent. The Image component usage properly preserves alt text and maintains semantic correctness.

Also applies to: 53-53, 86-86, 114-114, 145-145, 172-172, 202-202, 229-229


7-7: The /api/images endpoint properly serves images from blog article directories and other asset folders. The specific path in this file (/api/images/blog/best-ai-notetaker-for-in-person-meetings/cover.png) follows the correct format and will work as expected through the Supabase-backed proxy route.

However, pre-existing issues exist in other articles: best-ai-meeting-assistant-for-taking-notes.mdx and bot-free-ai-meeting-assistants.mdx contain malformed paths with duplicate /api/images/ prefixes and double slashes (//) that will fail sanitization and need correction.

Likely an incorrect or invalid review comment.

apps/web/content/articles/is-fireflies-ai-safe.mdx (1)

7-7: LGTM: Consistent image path migration.

All image references correctly updated to use internal API paths with proper Image component syntax.

Also applies to: 18-18, 75-75, 90-90, 103-103, 142-142

apps/web/content/articles/otter-ai-alternatives.mdx (1)

7-7: LGTM: Comprehensive image migration completed.

All cover and in-content images successfully migrated to internal API paths with correct Image component usage throughout the article.

Also applies to: 51-51, 67-67, 78-78, 85-85, 92-92, 99-99, 130-130, 154-154, 177-177, 207-207, 231-231, 257-257, 283-283, 309-309, 333-333, 359-359, 386-386, 410-410, 438-438

apps/web/content/articles/best-ai-notetaker-for-zoom.mdx (1)

7-7: LGTM: Image references properly updated.

All image paths correctly migrated with proper Image component syntax and preserved alt attributes.

Also applies to: 46-46, 90-90, 132-132, 168-168, 212-212, 250-250, 289-289, 324-324, 358-358, 394-394

apps/web/content/articles/free-ai-notetakers.mdx (1)

7-7: LGTM: All image assets migrated successfully.

Comprehensive migration of 18 images from external URLs to internal API paths, maintaining proper Image component usage and alt text throughout.

Also applies to: 34-34, 52-52, 66-66, 82-82, 95-95, 111-111, 128-128, 145-145, 164-164, 184-184, 201-201, 218-218, 233-233, 251-251, 267-267, 283-283, 296-296, 313-313

apps/web/content/articles/granola-ai-alternatives.mdx (1)

7-7: LGTM: Image migration completed correctly.

All images properly migrated to internal API paths with correct Image component syntax.

Also applies to: 33-33, 44-44, 63-63, 104-104, 135-135, 166-166, 199-199, 234-234

apps/web/content/articles/open-source-meeting-transcription-software.mdx (4)

42-42: Critical: Missing path separator in image URL.

The image path is missing a forward slash between the directory and filename, which will cause a 404 error.

Apply this diff to fix the path:

-<Image src="/api/images/blog/open-source-meeting-transcription-softwarehyprnote.webp" alt="Hyprnote"/>
+<Image src="/api/images/blog/open-source-meeting-transcription-software/hyprnote.webp" alt="Hyprnote"/>

Likely an incorrect or invalid review comment.


122-122: Critical: Missing path separator in image URL.

The image path is missing a forward slash between the directory and filename, which will cause a 404 error.

Apply this diff to fix the path:

-<Image src="/api/images/blog/open-source-meeting-transcription-software/amical.webp" alt="Amical"/>
+<Image src="/api/images/blog/open-source-meeting-transcription-software/amical.webp" alt="Amical"/>

Likely an incorrect or invalid review comment.


82-82: Critical: Missing path separator in image URL.

The image path is missing a forward slash between the directory and filename, which will cause a 404 error.

Apply this diff to fix the path:

-<Image src="/api/images/blog/open-source-meeting-transcription-software/meetily.webp" alt="Meetily"/>
+<Image src="/api/images/blog/open-source-meeting-transcription-software/meetily.webp" alt="Meetily"/>

Likely an incorrect or invalid review comment.


8-8: The cover image path is consistent with the established convention across all 36+ other articles in the codebase. The path /api/images/blog/open-source-meeting-transcription-software/cover.png correctly follows the {article-slug} naming pattern used throughout the site.

apps/web/content/articles/meeting-minutes-software.mdx (3)

7-7: Cover image proxied through /api/images looks consistent

Frontmatter now matches the new image proxy convention (/api/images/blog/meeting-minutes-software/cover.png); no issues from my side.


32-32: Image component migration for minutes-1–3 is clean

All three screenshots now use <Image> with the unified /api/images/blog/meeting-minutes-software/... prefix and descriptive alt text; this keeps assets consistent with the new proxy while preserving accessibility.

Also applies to: 56-56, 107-107


150-150: Remaining in-article images follow the same pattern

The minutes-4–7 assets are correctly pointed at /api/images/blog/meeting-minutes-software/*.webp and use clear, specific alt text; the migration to <Image> is consistent across the article.

Also applies to: 195-195, 239-239, 279-279

apps/web/content/articles/chatgpt-for-meeting-notes.mdx (2)

7-7: Cover image updated to internal image proxy

coverImage now points at /api/images/blog/chatgpt-for-meeting-notes/cover.png, matching the new internal routing convention.


85-85: Later illustrations (meeting notes, Hyprnote, pricing) look good

All three images are migrated to the /api/images proxy with descriptive alts (“chatgpt meeting notes”, “Hyprnote”, “Hyprnote pricing”) and use the shared <Image> component, which keeps rendering consistent across the article.

Also applies to: 177-177, 189-189

apps/web/src/components/mdx/callout.tsx (1)

1-31: Type-safe style map for callouts looks solid

Using CALLOUT_STYLES with as const gives you a nice keyof typeof CALLOUT_STYLES union for the type prop, and the icon/color definitions are clear and easy to extend later. No issues here.

Please just confirm that the icon names (e.g. mdi:information-outline, mdi:alert-outline) exist in your configured Iconify icon sets so there are no runtime “missing icon” placeholders.

apps/web/content/articles/is-otter-ai-safe.mdx (2)

27-27: First four Otter lawsuit visuals migrated cleanly

Images 1–4 now use <Image> with /api/images/blog/is-otter-ai-safe/otter-*.webp sources and specific alt text, which keeps the content accessible and standardized on the new proxy.

Also applies to: 52-52, 60-60, 66-66


74-74: Remaining images (5–10) follow the same /api/images + <Image> pattern

All later screenshots and policy excerpts are consistently wired to /api/images/blog/is-otter-ai-safe/otter-*.webp with descriptive alt attributes, so the article’s media pipeline is now fully aligned with the new Image component approach.

Also applies to: 80-80, 102-102, 110-110, 121-121, 137-137

@ComputelessComputer ComputelessComputer merged commit abc4c68 into main Dec 1, 2025
12 of 14 checks passed
@ComputelessComputer ComputelessComputer deleted the feat/image-component-and-proxy branch December 1, 2025 04:03
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.

2 participants