Conversation
Deploying newt239 with
|
| Latest commit: |
80db332
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://c2fadded.newt239-dev.pages.dev |
| Branch Preview URL: | https://feat-new-design.newt239-dev.pages.dev |
Cloudflare Pages のビルドで eslint@10.0.0 と @nuxt/eslint@1.14.0 の peer dependency 競合が発生していたため、eslint@^10.0.0 に対応した @nuxt/eslint@1.15.1 にアップグレード。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
サイト全体のデザイン刷新に合わせて、作品・記事一覧の操作性向上(フィルタ/ソート)と、作品詳細の画像体験(カルーセル+ライトボックス)を追加し、Nuxt Content の works スキーマを images[] ベースへ移行する PR です。
Changes:
- works スキーマを
thumbnail/altからimages: [{src, alt}]に変更し、既存作品メタデータを更新+新規作品(mmdash/omiya-fes)を追加 - 作品詳細に
ImageCarousel.vue/ImageLightbox.vueを追加し、OG/Twitter 画像参照もimages[0]へ変更 - 画像圧縮スクリプト(sharp)と npm script を追加
Reviewed changes
Copilot reviewed 37 out of 42 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/compress-images.ts | public/images を WebP 変換するユーティリティ追加 |
| public/images/mmdash.webp | 新規作品用画像追加 |
| pages/works/index.vue | 作品一覧におすすめフィルタ・並び順切替・空状態表示を追加 |
| pages/works/[...slug].vue | 作品詳細をカルーセル/ライトボックス対応、OG 画像を images[0] に変更 |
| pages/privacy.vue | レイアウト再構成(セクションカード化) |
| pages/articles/index.vue | 記事一覧にサイト別フィルタ・並び順切替・空状態表示を追加 |
| pages/about.vue | About ページをセクション化+リンクカード化 |
| package.json | sharp/@types/node 追加、画像圧縮 script 追加、@nuxt/eslint 更新 |
| content/works/sit-bus.md | images[] へ移行 |
| content/works/ship-notify.md | images[] へ移行 |
| content/works/sh309cafe.md | images[] へ移行 |
| content/works/score-watcher.md | images[] へ移行(alt 文面も短縮) |
| content/works/roomkeeper.md | images[] へ移行 |
| content/works/quiz-flasher.md | images[] へ移行 |
| content/works/portfolio.md | images[] へ移行 |
| content/works/omiya-fes.md | 新規作品追加(PNG 画像参照含む) |
| content/works/mojimachi.md | images[] へ移行 |
| content/works/mmdash.md | 新規作品追加(複数画像) |
| content/works/lounge-books.md | images[] へ移行 |
| content/works/look-inside-view.md | images[] へ移行 |
| content/works/local-font-emulator.md | images[] へ移行 |
| content/works/ginga-ui.md | images[] へ移行 |
| content/works/gateway.md | images[] へ移行 |
| content.config.ts | works スキーマを images[] 必須+ order/github 任意に変更 |
| components/WorkItem.vue | works カードを images[0] サムネ前提へ更新 |
| components/Timeline.vue | タイムライン UI を再設計(リンク/非リンク統合) |
| components/ThemeChanger.vue | テーマ生成 API に requiredVariables を追加、ボタン/UI 更新 |
| components/Profile.vue | プロフィールカード/UI 更新(導線文言変更) |
| components/MyTopTrackList.vue | トラック一覧 UI をカードグリッド化 |
| components/LatestArticleList.vue | 記事グリッドの列幅/配色を新トークンへ合わせ込み |
| components/ImageLightbox.vue | 新規:ライトボックス(ズーム/パン/キーボード操作) |
| components/ImageCarousel.vue | 新規:カルーセル(キーボード/タッチ操作) |
| components/Header.vue | ヘッダー配色・余白・ロゴサイズ更新 |
| components/Footer.vue | フッターをサイトマップ形式へ刷新 |
| components/FeaturedWorkList.vue | works グリッドの列幅/配色を新トークンへ合わせ込み |
| components/ArticleItem.vue | 記事カード UI を刷新(time 要素導入など) |
| assets/styles/main.css | CSS 変数を新トークン体系へ刷新 |
| AGENTS.md | works スキーマ説明を images[] 前提に更新 |
Comments suppressed due to low confidence (1)
pages/works/[...slug].vue:13
- 404 相当の SEO タイトルが
Not Foundedになっています。一般的にはNot Foundなので修正したほうがよいです(OG/Twitter 含む)。
pages/about.vue
Outdated
| <a href="https://bento.me/newt" target="_blank" class="link-card"> | ||
| Bento | ||
| <IconChevronRight :size="16" /> | ||
| </a> | ||
| <a href="https://annict.com/@newt" target="_blank" class="link-card"> | ||
| Annict | ||
| <IconChevronRight :size="16" /> | ||
| </a> |
There was a problem hiding this comment.
target="_blank" の外部リンク(Bento/Annict)に rel="noopener noreferrer" がありません。外部リンクは rel="noopener noreferrer" を付けてください。
components/Footer.vue
Outdated
| <a href="https://twitter.com/newt239" target="_blank"> | ||
| <IconBrandTwitter :size="18" /> | ||
| </a> | ||
| </li> | ||
| <li> | ||
| <a href="https://github.com/newt239" target="_blank"> |
There was a problem hiding this comment.
target="_blank" の外部リンクに rel="noopener noreferrer" がありません。Footer から外部サイトへ遷移するリンクには rel を付けてください。
| <a href="https://twitter.com/newt239" target="_blank"> | |
| <IconBrandTwitter :size="18" /> | |
| </a> | |
| </li> | |
| <li> | |
| <a href="https://github.com/newt239" target="_blank"> | |
| <a href="https://twitter.com/newt239" target="_blank" rel="noopener noreferrer"> | |
| <IconBrandTwitter :size="18" /> | |
| </a> | |
| </li> | |
| <li> | |
| <a href="https://github.com/newt239" target="_blank" rel="noopener noreferrer"> |
assets/styles/main.css
Outdated
| .sub { | ||
| font-size: 50%; | ||
| color: rgb(var(--color-text-secondary)); | ||
| color: rgb(var(--text-secondary)); |
There was a problem hiding this comment.
.sub の色指定で --text-secondary を参照していますが、:root では定義されていないため CSS 変数が解決できず意図しない色になります。--text-muted など既存トークンに合わせて修正してください。
| color: rgb(var(--text-secondary)); | |
| color: rgb(var(--text-muted)); |
| function goTo(index: number) { | ||
| if (isTransitioning.value) return; | ||
| isTransitioning.value = true; | ||
| currentIndex.value = ((index % props.images.length) + props.images.length) % props.images.length; | ||
| } | ||
|
|
||
| function prev() { | ||
| goTo(currentIndex.value - 1); | ||
| } | ||
|
|
||
| function next() { | ||
| goTo(currentIndex.value + 1); | ||
| } | ||
|
|
||
| function onTransitionEnd() { | ||
| isTransitioning.value = false; | ||
| } |
There was a problem hiding this comment.
prefers-reduced-motion: reduce で .carousel-track の transition が none になると transitionend が発火せず、isTransitioning が true のまま固定されて以後の操作が無効になります。Reduced motion 時は isTransitioning を使わない/即座に false に戻す、もしくは requestAnimationFrame/タイマーで解除する等の対応を入れてください。
| const route = useRoute(); | ||
| const router = useRouter(); | ||
|
|
||
| const sortAsc = ref(route.query.dir === "asc"); | ||
| const featuredOnly = ref(route.query.featured === "1"); | ||
|
|
There was a problem hiding this comment.
sortAsc / featuredOnly を route.query から初期化していますが、戻る/進む等でクエリだけが変わった場合に state が追従せず UI と URL が不整合になります。watch(() => route.query, ...) で ref を同期するか、クエリを source にした computed にして一貫性を保ってください。
components/ArticleItem.vue
Outdated
| <template> | ||
| <a :href="`${props.url}`" target="_blank" class="article-item"> | ||
| <div class="article-item-body"> | ||
| <a :href="`${props.url}`" target="_blank" class="article-card"> |
There was a problem hiding this comment.
target="_blank" の外部リンクに rel="noopener noreferrer" がありません(記事リンク)。外部リンクには rel を付けてください。
| <a :href="`${props.url}`" target="_blank" class="article-card"> | |
| <a :href="`${props.url}`" target="_blank" rel="noopener noreferrer" class="article-card"> |
| <dt>GitHub</dt> | ||
| <dd> | ||
| <a :href="`https://github.com/${data.github}`" target="_blank">{{ data.github }}</a> | ||
| </dd> |
There was a problem hiding this comment.
GitHub への外部リンクが target="_blank" ですが rel="noopener noreferrer" がありません。外部リンクには rel を付与してください。
| const route = useRoute(); | ||
| const router = useRouter(); | ||
|
|
||
| function parseSitesFromQuery(): Set<SiteName> { | ||
| const raw = route.query.sites; | ||
| if (!raw) return new Set(); | ||
| const arr = (typeof raw === "string" ? raw : raw[0] || "").split(",").filter(Boolean); | ||
| return new Set(arr as SiteName[]); | ||
| } | ||
|
|
||
| const selectedSites = ref<Set<SiteName>>(parseSitesFromQuery()); | ||
| const sortAsc = ref(route.query.dir === "asc"); | ||
|
|
||
| function updateQuery() { | ||
| const query: Record<string, string> = {}; | ||
| if (selectedSites.value.size > 0) query.sites = [...selectedSites.value].join(","); | ||
| if (sortAsc.value) query.dir = "asc"; | ||
| router.replace({ query }); | ||
| } |
There was a problem hiding this comment.
selectedSites / sortAsc を route.query から初期化していますが、戻る/進む等でクエリが変わったときに state が追従せず表示がズレます。watch(() => route.query, ...) で同期するか、クエリを source にした computed/useRouteQuery 相当のパターンに寄せてください。
components/WorkItem.vue
Outdated
| {{ props.work.description }} | ||
| </p> | ||
| <NuxtLink :to="`/works/${slug}`" class="work-card"> | ||
| <NuxtImg class="work-card-thumbnail" :src="`images/${thumbnail?.src}`" :alt="thumbnail?.alt" |
There was a problem hiding this comment.
サムネイルの src が images/... になっており、現在のパスに対する相対 URL として解釈される可能性があります(例: /works/images/...)。/images/... のようにルート相対にして 404 を避けてください。
| <NuxtImg class="work-card-thumbnail" :src="`images/${thumbnail?.src}`" :alt="thumbnail?.alt" | |
| <NuxtImg class="work-card-thumbnail" :src="`/images/${thumbnail?.src}`" :alt="thumbnail?.alt" |
| <ul> | ||
| <li> | ||
| <a href="https://discord.gg/rct5sx6rbZ" target="_blank">https://discord.gg/rct5sx6rbZ</a> | ||
| </li> |
There was a problem hiding this comment.
target="_blank" の外部リンクに rel="noopener noreferrer" が無く、window.opener 経由のタブナビング等のリスクがあります。外部リンクには rel="noopener noreferrer" を付けてください。
- 外部リンクに rel="noopener noreferrer" を追加 (about, Footer, ArticleItem, MyTopTrackList, works/[...slug]) - CSS変数 --text-secondary を既存の --text-muted に修正 - ImageCarousel で prefers-reduced-motion 時に isTransitioning が 固定される問題を修正 - works/index と articles/index で route.query の変更を watch で同期 - WorkItem のサムネイル src をルート相対パスに修正 - 404 ページの "Not Founded" を "Not Found" に修正 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
ImageCarousel.vue)とライトボックス(ImageLightbox.vue)コンポーネントを新規追加mmdashとomiya-fesを追加し、既存作品のメタデータ(images フィールド等)を更新scripts/compress-images.ts)を追加変更の詳細
assets/styles/main.cssのCSS変数・グローバルスタイルを更新content.config.tsのスキーマを変更(images フィールドの構造変更等)bun.lockの変更)Test plan
bun devでローカル開発サーバーが正常に起動することbun run generateで静的サイト生成が成功すること🤖 Generated with Claude Code