-
Notifications
You must be signed in to change notification settings - Fork 433
feat/image-component-and-proxy #2030
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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.
✅ Deploy Preview for hyprnote-storybook ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughReplaces external image URLs with internal Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
⏰ 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)
🔇 Additional comments (2)
Comment |
✅ Deploy Preview for hyprnote ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
There was a problem hiding this 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: AddImagecomponent 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 atapps/web/src/routes/_view/docs/-components.tsx(lines 111-127). This will cause a "Image is not defined" runtime error when the page renders. AddImageto 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.jpgand/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 topublic/images/.apps/web/content/articles/bot-free-ai-meeting-assistants.mdx (1)
7-52: Fix duplicatedapi/imagessegments in bot-free article paths
coverImageand 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” articleSeveral image URLs here don't match the
/api/images/blog/...pattern used elsewhere:
coverImageand 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/imagesproxy.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
widthandheightattributes 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/imagesThe
AUTHOR_AVATARSmap 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 sharedImagecomponent.apps/web/content/articles/chatgpt-for-meeting-notes.mdx (1)
10-10: Record mode screenshots wired to<Image>with consistent alt textBoth initial ChatGPT Record Mode screenshots correctly use
<Image>and the/api/images/blog/chatgpt-for-meeting-notes/chatgpt-*.webppaths. 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 fortype(and optional a11y role)Right now, an invalid
typecoming from MDX would makestyleundefined and throw atstyle.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
coverImageis 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
📒 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, usecn(import from@hypr/utils). It is similar toclsx. Always pass an array and split by logical grouping.
Usemotion/reactinstead offramer-motion.
Files:
apps/web/src/components/mdx/index.tsapps/web/src/routes/_view/blog/index.tsxapps/web/src/components/mdx/callout.tsxapps/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/imagesproxy 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/imagesendpoint 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/imagesproxy 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:
- The
/api/images/icons/competitors/logseq.pngendpoint is properly implemented in the application- The image asset is accessible via the proxy and returns a 200 status
- 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
coverImagepath update from Supabase URL to local API proxy is clean. However, ensure the/api/images/blog/sales-ai-note-takers/cover.pngendpoint 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
widthandheightprops. 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/imagesproxy route must exist, be performant, and serve images with appropriate cache headers. Direct Supabase CDN access typically has lower latency.Please confirm:
- 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?- 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/imagesroute 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
publishedfromtruetofalse, 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/imagesproxy paths looks systematic and consistent across all instances (lines 8, 51, 102, 154, 216, 267, 316). However, confirm:
- The
Imagecomponent is properly imported in this MDX file's rendering context.- The
/api/images/blog/plaud-ai-alternatives/*endpoints exist and correctly resolve the referenced images.- The
Imagecomponent definition supports thesrcandaltprops as used here.apps/web/content/vs/reflect.mdx (1)
3-3: Verification complete:/api/imagesendpoint and path mapping are properly implemented.The endpoint at
apps/web/src/routes/api/images.$.tscorrectly 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 URLsThe migration is complete and functioning as intended.
apps/web/content/vs/bluedot.mdx (1)
3-3: No action needed — the/api/imagesproxy 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.jpgfollows 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 atapps/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 inapps/web/src/routes/api/images.$.tswith:
- 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 MDXContentcomponentsprop 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/imageproperly accepts thesrcandaltprops 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/imagesroute 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 inapps/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/imagesendpoint is properly implemented and handles the icon proxy paths correctly. The path/api/images/icons/competitors/fathom.pngfollows 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/imagesproxy route is properly configured and operational. The route handler atapps/web/src/routes/api/images.$.tsimplements 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. TheImagecomponent is properly exported and integrated into the MDX rendering pipeline atapps/web/src/routes/_view/blog/$slug.tsx. The/api/imagesroute is configured to proxy images from Supabase storage, so the image paths will resolve correctly.
7-7: ThecoverImagefrontmatter is correctly processed in the blog rendering pipeline. TheCoverImagecomponent inapps/web/src/routes/_view/blog/$slug.tsxretrieves the frontmatter field and passes it to theImagecomponent, which uses@unpic/reactfor 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 atpublic_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
coverImagepath has been successfully migrated to the/api/imagesproxy pattern, consistent with the PR objectives.
30-30: Image components properly implemented with descriptive alt text.All
<Image>components are correctly self-closing with descriptivealtattributes, 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 toMDXContentin 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/imagesproxy endpoint is fully configured. The component doesn't require explicit imports in the MDX file because it's registered via thecomponentsprop inArticleContent(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 withlayout="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:
✓ Image component integration: The
Imagecomponent is properly imported in the blog route (apps/web/src/routes/_view/blog/$slug.tsxline 11) and available for MDX rendering via the content-collections pipeline.✓ API endpoint functionality: The
/api/imagesproxy 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.).✓ Complete migration: All 313
/api/imagesreferences in 153 content files have been successfully migrated with zero external URLs remaining — full migration verified.✓ 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/imagesURLs with correct format handling (.pngand.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.pngreturns the expected image.
48-48: No issues found. TheCtaCardcomponent is properly imported in the blog route (/src/routes/_view/blog/$slug.tsxline 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 ofapps/web/src/routes/_view/blog/$slug.tsxand passed toMDXContentat line 329). The component uses@unpic/react, which is a responsive image library that does not require explicitwidthandheightprops—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
coverImagehas been migrated to an internal API route. Ensure the image file exists at/api/images/blog/why-our-cms-is-github/cover.pngand 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 withsrc,alt, andtitleprops. Ensure:
- The Image component is exported from
apps/web/src/components/mdx/index.ts(or equivalent)- It's registered in the MDX components map for this doc route
- Image files exist at the referenced paths (
/api/images/docs/pro/activation-1.pngandactivation-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.pngand 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/imagespaths requires that the backend image proxy is implemented and correctly maps all paths. Please confirm the/api/images/icons/competitors/notability.pngendpoint 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.pngendpoint 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.jpegcorrectly 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:
- The Image component is properly exported from
apps/web/src/components/mdx/index.ts- The
/api/images/blog/is-ai-notetaking-legal/cover.pngendpoint resolves
163-163: Verify Image component receives correct props and renders.The
<Image>component is now used withsrcandaltprops. Confirm the component signature accepts these props and doesn't require additional required props (e.g.,width,heightfor 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.pngfollowing 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.jpgwithin 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.pngconsistent 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/imagesroutes. Before merging, confirm:
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
All image paths exist — Run a validation check across all modified files to confirm no 404s will occur
Image component exports — Verify
apps/web/src/components/mdx/index.tsexports theImagecomponent and it's registered with the MDX renderer in blog routesapps/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
Imagecomponent 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
.jpgwhile 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
Imagecomponent properly handles both.pngand.webpformats, 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.jpegextension; 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:hiddenandhidden dark:blockclassName 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 topublished: truefor 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:
- The Callout component is properly exported from
apps/web/src/components/mdx/index.ts- The blog route rendering integration (mentioned in AI summary) properly surfaces Callout to MDX consumers
- The component accepts and renders the
typeprop correctlyapps/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 explicitwidthandheightattributes, 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/imagesendpoint handles both.pngand.jpgextensions consistently with proper Content-Type headers.apps/web/content/vs/obsidian.mdx (1)
3-3: Icon path normalization looks correct
iconnow 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 consistentAll 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 cleanCover 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 correctlyAdding
export { Callout } from "./callout";cleanly extends the MDX components surface alongsideMermaidandTweet.apps/web/content/articles/tldv-review.mdx (1)
8-209: tl;dv review images correctly migratedAll 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 (
Imageandimg: Image) ensures both explicit<Image>components and standard Markdownsyntax 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/imagesendpoint 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.mdxandbot-free-ai-meeting-assistants.mdxcontain 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.pngcorrectly 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/imageslooks consistentFrontmatter 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 cleanAll 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 patternThe minutes-4–7 assets are correctly pointed at
/api/images/blog/meeting-minutes-software/*.webpand 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
coverImagenow 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 goodAll three images are migrated to the
/api/imagesproxy 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 solidUsing
CALLOUT_STYLESwithas constgives you a nicekeyof typeof CALLOUT_STYLESunion for thetypeprop, 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 cleanlyImages 1–4 now use
<Image>with/api/images/blog/is-otter-ai-safe/otter-*.webpsources 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>patternAll later screenshots and policy excerpts are consistently wired to
/api/images/blog/is-otter-ai-safe/otter-*.webpwith 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
Imagecomponent in blog articles/api/images