Conversation
🔧 | Also, Fix some files
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded@T-b-t-nchos has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 18 minutes and 36 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (2)
WalkthroughMarkdown処理ライブラリとTailwind Typographyを追加し、 Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User
participant BlogList as ブログ一覧 (src/app/blog/page.tsx)
participant BlogPost as 個別記事 (src/app/blog/[slug]/page.tsx)
participant Posts as posts.ts (src/lib/posts.ts)
participant FS as ファイルシステム
participant Remark as remark (remark-html)
rect rgb(230,245,255)
User->>BlogList: /blog にアクセス
BlogList->>Posts: getAllPosts()
Posts->>FS: posts/ ディレクトリを読み込む
FS-->>Posts: Markdown ファイル一覧/内容
Posts->>Posts: gray-matter で front matter と content をパース
Posts-->>BlogList: 投稿配列を返却
BlogList-->>User: 投稿リストを表示
end
rect rgb(245,255,230)
User->>BlogPost: /blog/[slug] にアクセス
BlogPost->>Posts: getPostBySlug(slug)
Posts->>FS: 指定ファイルを読み込む
FS-->>Posts: ファイル内容
Posts->>BlogPost: { slug, meta, content }
BlogPost->>Remark: remark + remark-html で Markdown を HTML に変換
Remark-->>BlogPost: HTML
BlogPost-->>User: HTML をレンダリング(dangerouslySetInnerHTML)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/app/globals.css (1)
28-30: Tailwind CSS v4では@tailwindディレクティブは非推奨です。Tailwind CSS v4を使用している場合(package.jsonで
tailwindcss: ^4.1.16を使用)、@tailwind base/components/utilitiesディレクティブは不要です。1行目の@import "tailwindcss"で十分です。このファイルはTailwind v3とv4の構文が混在しており、予期しない動作を引き起こす可能性があります。
以下のdiffを適用して、非推奨のディレクティブを削除してください:
-@tailwind base; -@tailwind components; -@tailwind utilities; - @layer base {
🧹 Nitpick comments (4)
posts/251029_BornBlog.md (2)
43-47: コードブロックに言語指定を追加することをお勧めします。Markdownのベストプラクティスとして、コードブロックには言語を指定することが推奨されます。これにより、適切なシンタックスハイライトが適用されます。
以下のように修正することをお勧めします:
-``` +```text This is CodeBlock Line 1. This is CodeBlock Line 2. This is CodeBlock Line 3.または、実際のコードの場合は適切な言語(`javascript`、`python`など)を指定してください。 --- `30-32`: **リストのインデントを調整することをお勧めします。** Markdownのベストプラクティスとして、サブアイテムは2スペースでインデントすることが推奨されます(現在は4スペース)。 以下のように修正することをお勧めします: ```diff * 順序無しリストのアイテム - * サブアイテムはタブもしくは4つのスペースでインデントする + * サブアイテムはタブもしくは2つのスペースでインデントする * 順序無しリストの別のアイテムsrc/app/blog/page.tsx (1)
2-2: 未使用のインポートを削除してください。
Imageコンポーネントがインポートされていますが、このファイル内で使用されていません。以下のdiffを適用してください:
import Link from "next/link"; -import Image from "next/image"; import { getAllPosts } from "@/lib/posts";src/app/blog/[slug]/page.tsx (1)
15-20: エラーハンドリングの追加を検討
getPostBySlugが存在しないスラグで呼ばれた場合や、Markdownの処理に失敗した場合のエラーハンドリングがありません。Next.js のnotFound()を使用して404ページを表示することを推奨します。以下の実装例を参考にしてください:
import { notFound } from 'next/navigation'; export default async function PostPage({ params }: Props) { const { slug } = await params; try { const post = getPostBySlug(slug); if (!post) { notFound(); } const processedContent = await remark().use(html).process(post.content); const contentHtml = processedContent.toString(); // ... rest of the code } catch (error) { notFound(); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (9)
package.json(1 hunks)posts/251029_BornBlog.md(1 hunks)src/app/blog/[slug]/page.tsx(1 hunks)src/app/blog/page.tsx(1 hunks)src/app/globals.css(1 hunks)src/app/layout.tsx(1 hunks)src/app/page.tsx(2 hunks)src/lib/posts.ts(1 hunks)tailwind.config.js(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/app/blog/page.tsx (1)
src/lib/posts.ts (1)
getAllPosts(7-23)
src/app/blog/[slug]/page.tsx (1)
src/lib/posts.ts (2)
getAllPosts(7-23)getPostBySlug(25-31)
🪛 ast-grep (0.39.6)
src/app/blog/[slug]/page.tsx
[warning] 43-43: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
🪛 Biome (2.1.2)
src/app/blog/[slug]/page.tsx
[error] 44-44: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
🪛 LanguageTool
posts/251029_BornBlog.md
[uncategorized] ~26-~26: 「ことができる」という表現は冗長な可能性があります。
Context: ...lockquote要素はreflowableです。テキストを好きなように 改行することができます。改行したとしても、変換後はひとつの blockquote要素として扱われ...
(DOUSI_KOTOGADEKIRU)
🪛 markdownlint-cli2 (0.18.1)
posts/251029_BornBlog.md
31-31: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
43-43: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (9)
src/app/globals.css (1)
32-173: プロススタイリングの実装を承認します。
.proseクラス用の包括的なスタイリングが適切に実装されています。見出し、リスト、リンク、コードブロックなど、すべての主要なMarkdown要素がカバーされています。src/app/page.tsx (1)
36-44: 内部ナビゲーションにLinkを使用する変更を承認します。
<a>タグから<Link>コンポーネントへの変更は、Next.jsのクライアントサイドルーティングを活用するための適切な改善です。これによりページ遷移が高速化されます。src/app/blog/page.tsx (1)
5-41: ブログリストページの実装を承認します。投稿リストの表示、日付のフォーマット、個別投稿へのリンクなど、ブログリストページの実装は適切です。UIも洗練されており、ホバーエフェクトも効果的です。
src/app/layout.tsx (1)
30-32: 背景画像の存在確認が完了しました。
/bk1.pngファイルがpublicディレクトリに正常に存在することが確認されました(2.8M)。コード変更に問題はありません。package.json (1)
12-20: 検証完了: すべての依存関係は最新バージョンで、既知の脆弱性はありません。実施した確認により、追加された依存関係はすべて最新バージョンであることが確認されました:
- gray-matter@4.0.3、react-markdown@10.1.0、rehype-raw@7.0.0、remark@15.0.1、remark-gfm@4.0.1、remark-html@16.0.1、@tailwindcss/typography@0.5.19
脆弱性スキャンでも既知の脆弱性は検出されていません。現在のパッケージ構成は安全で適切です。
src/app/blog/[slug]/page.tsx (4)
6-13: Next.js 15のパターンに準拠しています
paramsがPromiseとして正しく型定義されており、generateStaticParamsの実装も適切です。ただし、
getAllPosts()がファイルシステム操作に失敗した場合のエラーハンドリングが不足しています。src/lib/posts.tsでエラーハンドリングが実装されているか確認することをお勧めします。
27-33: 日付のバリデーションを検討
post.meta.dateが有効な日付文字列であることを前提としていますが、無効な値の場合にInvalid Dateが表示される可能性があります。マークダウンファイルの frontmatter で日付形式が統一されているか確認してください。
42-45: XSSリスクは限定的ですが、コンテンツの出所を文書化してください静的解析ツールが
dangerouslySetInnerHTMLの使用を警告していますが、コンテンツがローカルのMarkdownファイルから読み込まれているため、XSSリスクは低いと判断できます。ただし、将来的にユーザー生成コンテンツを扱う可能性がある場合は、DOMPurifyなどのサニタイズライブラリの導入を検討してください。
コンテンツソースが信頼できることを確認済みであれば問題ありません。
1-55: 全体的に良好な実装ですブログ記事ページの実装は、Next.js 15のベストプラクティスに従っており、適切な静的生成とMarkdown処理が実装されています。Tailwind CSS v4のクラスも正しく使用されています。
主な改善点:
- デバッグ用の
console.logを削除- 相対パスを絶対パスに修正
- エラーハンドリングの追加を検討
- 日付の妥当性確認
これらの軽微な改善を行えば、本番環境で使用可能な品質になります。
cdc4230 to
467da5f
Compare
- Add file filtering - Error handling
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/lib/posts.ts (1)
33-39: エラーハンドリングが依然として欠けています(未解決)。前回のレビューで指摘されたエラーハンドリングがまだ実装されていません。存在しないスラッグが指定された場合、
fs.readFileSyncが例外をスローし、アプリケーションがクラッシュします。以下の修正を適用してください:
export function getPostBySlug(slug: string) { + try { - const fullPath = path.join(postsDirectory, `${slug}.md`); - const fileContents = fs.readFileSync(fullPath, "utf8"); - const { data, content } = matter(fileContents); + const fullPath = path.join(postsDirectory, `${slug}.md`); + + if (!fs.existsSync(fullPath)) { + throw new Error(`Post not found: ${slug}`); + } + + const fileContents = fs.readFileSync(fullPath, "utf8"); + const { data, content } = matter(fileContents); - return { slug, meta: data, content }; + return { slug, meta: data, content }; + } catch (error) { + console.error(`Error reading post ${slug}:`, error); + throw error; + } }src/app/blog/[slug]/page.tsx (1)
27-31: 日付の妥当性検証を追加してください。
post.meta.dateが無効な日付形式の場合、new Date()は "Invalid Date" を返し、ユーザーに表示されます。日付のバリデーションまたはフォールバック処理を追加することをお勧めします。以下の修正を適用してください:
- <p className="text-sm text-green-400 tracking-wide uppercase"> - {new Date(post.meta.date).toLocaleDateString("ja-JP", { - year: "numeric", - month: "long", - day: "numeric", - })} - </p> + {post.meta.date && ( + <p className="text-sm text-green-400 tracking-wide uppercase"> + {(() => { + const date = new Date(post.meta.date); + return isNaN(date.getTime()) + ? post.meta.date + : date.toLocaleDateString("ja-JP", { + year: "numeric", + month: "long", + day: "numeric", + }); + })()} + </p> + )}
🧹 Nitpick comments (1)
src/app/globals.css (1)
28-169: テーマシステムとの統合を推奨します。
.proseスタイルは機能的に正しいですが、以下の改善を検討してください:
CSS変数の活用: 色やフォントにハードコードされた値(
#f7fafc、#4a5568、"Fira Code"など)が使用されていますが、既存のCSS変数(--foreground、--font-monoなど)を使用すると、テーマの一貫性が保たれます。ダークモード対応: ルートレベルでダークモードが定義されていますが、
.proseスタイルはこれに適応していません。prefers-color-schemeメディアクエリを追加するか、CSS変数を使用して自動的に適応させることをお勧めします。Tailwind Typographyプラグインとの重複: このPRで
@tailwindcss/typographyプラグインが追加されていますが、カスタム.proseスタイルと競合する可能性があります。プラグインのデフォルトスタイルを拡張する形にするか、完全にカスタムスタイルにするか明確にすることをお勧めします。以下のような改善案を検討してください:
@layer base { .prose { - color: #f7fafc; + color: var(--foreground); } /* コードブロック */ .prose code { - font-family: "Fira Code", monospace; + font-family: var(--font-mono); } .prose pre { - font-family: "Fira Code", monospace; + font-family: var(--font-mono); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (6)
package.json(1 hunks)src/app/blog/[slug]/page.tsx(1 hunks)src/app/globals.css(1 hunks)src/app/page.tsx(2 hunks)src/lib/posts.ts(1 hunks)tailwind.config.js(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- package.json
- src/app/page.tsx
- tailwind.config.js
🧰 Additional context used
🧬 Code graph analysis (1)
src/app/blog/[slug]/page.tsx (1)
src/lib/posts.ts (2)
getAllPosts(7-31)getPostBySlug(33-39)
🪛 ast-grep (0.39.6)
src/app/blog/[slug]/page.tsx
[warning] 42-42: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
🪛 Biome (2.1.2)
src/app/blog/[slug]/page.tsx
[error] 43-43: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
🔇 Additional comments (3)
src/lib/posts.ts (1)
7-31: 実装が改善されています!前回のレビューコメントが適切に対応されています:
.mdファイルのフィルタリング- try-catchによるエラーハンドリング
- 失敗した投稿の除外
src/app/blog/[slug]/page.tsx (2)
10-13: 静的パラメータ生成の実装が正しいです。Next.js 15の新しい非同期APIパターンに適合しており、
getAllPosts()を使用して静的ルートを生成しています。
41-44:dangerouslySetInnerHTMLの使用について確認してください。静的解析ツールがXSSリスクを指摘しています。このケースでは、以下の理由から比較的安全です:
- コンテンツソース: Markdownファイルはローカルの
posts/ディレクトリから読み込まれ、開発者が管理しています(ユーザー入力ではありません)- remark-html: デフォルトでHTMLをエスケープする機能があります
ただし、以下の点を確認してください:
- Markdownファイルが信頼できるソースからのみ提供されることを確認
- 将来的にユーザー生成コンテンツを扱う場合は、DOMPurifyなどのサニタイズライブラリの使用を検討
より安全な実装が必要な場合は、以下のようにDOMPurifyを使用することをお勧めします:
import DOMPurify from 'isomorphic-dompurify'; // ... const sanitizedHtml = DOMPurify.sanitize(contentHtml); <div className="prose prose-invert lg:prose-xl max-w-none" dangerouslySetInnerHTML={{ __html: sanitizedHtml }} />
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
posts/251029_BornBlog.md (1)
28-31: テキスト表現の最適化を検討してください30 行目の「ことができます。改行したとしても」という表現について、LanguageTool が「ことができる」表現の冗長性を指摘しています。以下のような表現への修正を検討ください:
修正例:
- > blockquote要素はreflowableです。テキストを好きなように - > 改行することができます。改行したとしても、変換後はひとつの + > blockquote要素はreflowableです。テキストを好きなように + > 改行できます。改行しても、変換後はひとつのより簡潔な表現への改善をご検討ください。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
posts/251029_BornBlog.md(1 hunks)
🧰 Additional context used
🪛 LanguageTool
posts/251029_BornBlog.md
[uncategorized] ~30-~30: 「ことができる」という表現は冗長な可能性があります。
Context: ...ockquote要素はreflowableです。テキストを好きなように > 改行することができます。改行したとしても、変換後はひとつの > blockquote要素として...
(DOUSI_KOTOGADEKIRU)
🪛 markdownlint-cli2 (0.18.1)
posts/251029_BornBlog.md
43-43: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (1)
posts/251029_BornBlog.md (1)
1-5: YAML フロントマター形式は正しい ✓ブログポストのメタデータ(
title、date、description)が適切に定義されています。日付形式も ISO 8601(YYYY-MM-DD)で統一されており、ブログ読込ユーティリティの期待形式と合致しています。
Close: #1
Summary by CodeRabbit
新機能
スタイル
その他