Skip to content

refactor(ui): redesign footer with sectioned columns, logo, and social links#2614

Merged
alexdln merged 7 commits intonpmx-dev:mainfrom
j0u1:refactor/footer
Apr 22, 2026
Merged

refactor(ui): redesign footer with sectioned columns, logo, and social links#2614
alexdln merged 7 commits intonpmx-dev:mainfrom
j0u1:refactor/footer

Conversation

@j0u1
Copy link
Copy Markdown
Contributor

@j0u1 j0u1 commented Apr 21, 2026

🧭 Context

The footer had a flat single-row link layout. As the project grows, it needed better structure and visual identity.

📚 Description

Redesigned the footer from a flat inline link list to a multi-column sectioned layout:

Added logo and social icons (GitHub, Discord, Bluesky)
Grouped links into sections: Resources, Features, Other
Added footer variant to LinkBase for consistent footer-specific styling
Moved keyboard shortcuts modal to the bottom of the footer
Minor: fixed text-left → text-start for RTL compatibility, kbd size text-sm → text-xs

Screenshot

Footer as implemented (based on Figma design)
изображение

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 21, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Apr 22, 2026 1:55pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Apr 22, 2026 1:55pm
npmx-lunaria Ignored Ignored Apr 22, 2026 1:55pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Refactored the footer component to use data-driven rendering via computed properties and loops instead of hard-coded markup. Expanded all 27+ translation locale files with new UI keys for footer sections, command palette, timeline, settings, and chart features. Updated the i18n schema to reflect new footer properties.

Changes

Cohort / File(s) Summary
Footer Component
app/components/AppFooter.vue
Restructured to render footer links and sections dynamically from computed footerSections array and socialLinks. Updated responsive visibility classes and moved keyboard shortcuts modal. Changed .kbd styling from text-sm to text-xs.
i18n Schema
i18n/schema.json
Extended footer object properties to include three new required string fields: resources, features, and other.
Locale Files – English & European Languages
i18n/locales/en.json, i18n/locales/de.json, i18n/locales/fr-FR.json, i18n/locales/es.json, i18n/locales/it-IT.json, i18n/locales/cs-CZ.json, i18n/locales/nl.json, i18n/locales/pl-PL.json, i18n/locales/pt-BR.json, i18n/locales/ru-RU.json
Added footer sections (resources, features, other), new shortcut labels, timeline strings, and package-related UI translations. Most new entries are placeholder English text awaiting localisation.
Locale Files – Nordic Languages
i18n/locales/nb-NO.json, i18n/locales/uk-UA.json
Extended footer navigation, shortcuts, and package sections with new timeline/comparison/chart UI strings and facet metadata keys. Additional placeholder English entries added.
Locale Files – Eastern European Languages
i18n/locales/bg-BG.json, i18n/locales/hu-HU.json, i18n/locales/sr-Latn-RS.json, i18n/locales/tr-TR.json
Added comprehensive new translation namespaces: command_palette, timeline, scatter chart labels, version/compare UI, and brand/vacations sections. Replaced previously-empty objects with populated structures across multiple feature areas.
Locale Files – South Asian Languages
i18n/locales/ar.json, i18n/locales/bn-IN.json, i18n/locales/hi-IN.json, i18n/locales/kn-IN.json, i18n/locales/mr-IN.json, i18n/locales/ne-NP.json, i18n/locales/ta-IN.json, i18n/locales/te-IN.json
Substantially expanded with new feature translations including command palette, instant search toggles, error messages by status code, timeline events, code viewer controls, compare UI, and brand/PDS/translation-status pages. Many previously-empty sections now populated with placeholder text.
Locale Files – East Asian Languages
i18n/locales/ja-JP.json, i18n/locales/zh-CN.json, i18n/locales/zh-TW.json
Added timeline section, footer resources/features/other, package replacement examples, code ligatures setting, and new comparison facet labels (GitHub stars/issues/created at). Expanded with command palette and chart-related UI strings in Japanese; minimal updates for Chinese variants.
Locale Files – Southeast Asian & Other Languages
i18n/locales/az-AZ.json, i18n/locales/id-ID.json, i18n/locales/vi-VN.json
Added new footer sections, command palette namespace, timeline UI, settings toggles (code ligatures, instant search), and comparison/scatter chart labels. Populated previously-empty objects for brand, vacations, and action bar sections.

Possibly related PRs

Suggested reviewers

  • serhalp
  • graphieros
  • alexdln
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: redesigning the footer from a flat layout to a multi-column sectioned design with logo and social links.
Description check ✅ Passed The description is directly related to the changeset, providing context for the footer redesign, listing specific improvements (logo, social icons, sections), and including a screenshot of the implementation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

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

@j0u1 j0u1 changed the title feat(footer): redesign with sectioned columns, logo, and social links refactor(ui): redesign footer with sectioned columns, logo, and social links Apr 21, 2026
Copy link
Copy Markdown
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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/components/AppFooter.vue`:
- Around line 104-112: The social icon links rendered in the AppFooter.vue using
the <component> tag produce nothing (no :is prop) and lack accessible names;
update the NuxtLink loop that iterates socialLinks to render a <span> (or
another non-VNode wrapper) instead of <component> for CSS-only Iconify classes
and add an aria-label attribute on the NuxtLink (e.g., :aria-label="link.label
|| link.id") so each link has a descriptive accessible name; ensure the existing
class binding (link.icon and size-7) moves to the <span> while preserving
target="_blank" and other NuxtLink props.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 917b9cc7-5c31-4984-b5c2-dae916570de9

📥 Commits

Reviewing files that changed from the base of the PR and between c8fcd11 and c01e64c.

📒 Files selected for processing (2)
  • app/components/AppFooter.vue
  • app/components/Link/Base.vue

Comment thread app/components/AppFooter.vue
Copy link
Copy Markdown
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.

♻️ Duplicate comments (1)
app/components/AppFooter.vue (1)

104-113: ⚠️ Potential issue | 🔴 Critical

Social icons still render nothing, and aria-label uses the lowercase id instead of a brand name.

Two issues remain from the prior review:

  1. <component :class="link.icon" class="size-7" /> has no :is prop. In Vue 3, <component> without :is resolves to NULL_DYNAMIC_COMPONENT and renders nothing, so the GitHub/Discord/Bluesky icons won't appear on the page. For a CSS-only Iconify class, use a plain <span> with aria-hidden="true".
  2. :aria-label="link.id" announces "github", "discord", "bluesky" to screen readers. Use the proper brand label (e.g. GitHub, Discord, Bluesky) so assistive tech reads the correct product name.
🛠️ Proposed fix
 const socialLinks = computed(() => [
   {
     id: 'github',
+    label: 'GitHub',
     href: 'https://repo.npmx.dev',
     icon: 'i-simple-icons:github',
   },
   {
     id: 'discord',
+    label: 'Discord',
     href: discord.value.url,
     icon: 'i-simple-icons:discord',
   },
   {
     id: 'bluesky',
+    label: 'Bluesky',
     href: 'https://social.npmx.dev',
     icon: 'i-simple-icons:bluesky',
   },
 ])
 <NuxtLink
   v-for="link in socialLinks"
   :key="link.id"
   :to="link.href"
-  :aria-label="link.id"
+  :aria-label="link.label"
   target="_blank"
   class="text-fg-muted hover:text-accent transition-all duration-200"
 >
-  <component :class="link.icon" class="size-7" />
+  <span :class="link.icon" class="size-7" aria-hidden="true" />
 </NuxtLink>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/AppFooter.vue` around lines 104 - 113, The social icons aren’t
rendering because the <component> tag lacks an :is prop and screen readers get
wrong labels from :aria-label="link.id"; update the NuxtLink loop that uses
socialLinks so that icon rendering uses a CSS-only element for class-based
Iconify icons (replace <component :class="link.icon" ... /> with a <span> and
aria-hidden="true" when link.icon is a CSS class) or provide the actual
component via :is when using dynamic components, and change
:aria-label="link.id" to use the proper brand name (e.g. link.label or a mapped
string like "GitHub", "Discord", "Bluesky") so NuxtLink renders accessible
product names; adjust socialLinks entries or transform within the template to
supply the correct label and icon handling.
🧹 Nitpick comments (2)
app/components/AppFooter.vue (2)

126-138: Button branch doesn't match LinkBase footer styling, and :key is duplicated.

Minor polish for the two render branches:

  • The <button> for the keyboard-shortcuts entry lacks the lowercase utility that LinkBase applies for variant="footer" (see app/components/Link/Base.vue line 107: text-fg-subtle text-sm cursor-pointer lowercase). If the i18n value for footer.keyboard_shortcuts ever comes through title-cased, the button will render inconsistently with its sibling links in the same column.
  • :key="link.name" is set on both the <template v-for> wrapper and the inner <LinkBase>. The inner key is redundant — only the <template> key matters here.
♻️ Proposed tidy-up
 <button
   v-if="link.type === 'button'"
-  class="cursor-pointer text-start font-mono text-fg-subtle text-sm hover:text-accent transition-colors duration-200"
+  class="cursor-pointer text-start font-mono text-fg-subtle text-sm lowercase hover:text-accent transition-colors duration-200"
   `@click`="showModal()"
 >
   {{ $t(link.name) }}
 </button>

-<LinkBase v-else :key="link.name" :to="link?.href" variant="footer">
+<LinkBase v-else :to="link?.href" variant="footer">
   {{ $t(link.name) }}
 </LinkBase>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/AppFooter.vue` around lines 126 - 138, The button branch in
the v-for needs to match LinkBase's footer styling and remove the redundant
inner key: add the "lowercase" utility (so its classes mirror LinkBase
variant="footer" such as text-fg-subtle text-sm cursor-pointer lowercase) to the
<button> rendered for the keyboard-shortcuts entry and remove the duplicate
:key="link.name" on the inner <LinkBase> (keep the :key on the <template
v-for="link in section.links"> only); the handler showModal() and the link.name
identifier remain unchanged.

13-16: Unused kbd variant in FooterLink union.

The { name: string; kbd: string; ... } member of the FooterLink union is not used by any entry in footerSections, and the template has no branch that renders a kbd link either. Either drop the variant or wire it up so the types stay honest.

♻️ Proposed simplification
 type FooterLink =
   | { name: string; href: string; kbd?: never; type?: never }
-  | { name: string; kbd: string; href?: never; type?: never }
   | { name: string; type: 'button'; href?: never; kbd?: never }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/AppFooter.vue` around lines 13 - 16, The FooterLink union
includes an unused kbd variant; remove the `{ name: string; kbd: string; href?:
never; type?: never }` member from the FooterLink type and update usages so
FooterLink only has the anchor and button shapes, then ensure footerSections
entries and the AppFooter.vue template continue to type-check against the
simplified union (or alternatively, if you prefer to keep keyboard shortcuts,
add entries to footerSections with kbd fields and add a template branch that
renders kbd links using type guards—pick one approach and make the corresponding
change to FooterLink, footerSections, and the template).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@app/components/AppFooter.vue`:
- Around line 104-113: The social icons aren’t rendering because the <component>
tag lacks an :is prop and screen readers get wrong labels from
:aria-label="link.id"; update the NuxtLink loop that uses socialLinks so that
icon rendering uses a CSS-only element for class-based Iconify icons (replace
<component :class="link.icon" ... /> with a <span> and aria-hidden="true" when
link.icon is a CSS class) or provide the actual component via :is when using
dynamic components, and change :aria-label="link.id" to use the proper brand
name (e.g. link.label or a mapped string like "GitHub", "Discord", "Bluesky") so
NuxtLink renders accessible product names; adjust socialLinks entries or
transform within the template to supply the correct label and icon handling.

---

Nitpick comments:
In `@app/components/AppFooter.vue`:
- Around line 126-138: The button branch in the v-for needs to match LinkBase's
footer styling and remove the redundant inner key: add the "lowercase" utility
(so its classes mirror LinkBase variant="footer" such as text-fg-subtle text-sm
cursor-pointer lowercase) to the <button> rendered for the keyboard-shortcuts
entry and remove the duplicate :key="link.name" on the inner <LinkBase> (keep
the :key on the <template v-for="link in section.links"> only); the handler
showModal() and the link.name identifier remain unchanged.
- Around line 13-16: The FooterLink union includes an unused kbd variant; remove
the `{ name: string; kbd: string; href?: never; type?: never }` member from the
FooterLink type and update usages so FooterLink only has the anchor and button
shapes, then ensure footerSections entries and the AppFooter.vue template
continue to type-check against the simplified union (or alternatively, if you
prefer to keep keyboard shortcuts, add entries to footerSections with kbd fields
and add a template branch that renders kbd links using type guards—pick one
approach and make the corresponding change to FooterLink, footerSections, and
the template).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 16b65b05-118f-4811-bbdb-7ebee1960835

📥 Commits

Reviewing files that changed from the base of the PR and between c01e64c and ded091f.

📒 Files selected for processing (1)
  • app/components/AppFooter.vue

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 21, 2026

Codecov Report

❌ Patch coverage is 96.72131% with 2 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
app/components/AppFooter.vue 96.72% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
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: 1

🧹 Nitpick comments (1)
app/components/AppFooter.vue (1)

13-16: Keep FooterLink aligned with the rendered branches.

FooterLink permits a kbd-only entry, but the template only distinguishes buttons from links; a future kbd item would fall through to <LinkBase> with to undefined. Please verify whether this variant is reserved for a follow-up; otherwise remove it and pass link.href directly. As per coding guidelines, **/*.{ts,tsx,vue} should ensure strictly type-safe code.

Suggested change if `kbd` is not needed
 type FooterLink =
   | { name: string; href: string; kbd?: never; type?: never }
-  | { name: string; kbd: string; href?: never; type?: never }
   | { name: string; type: 'button'; href?: never; kbd?: never }
...
-              <LinkBase v-else :key="link.name" :to="link?.href" variant="footer">
+              <LinkBase v-else :key="link.name" :to="link.href" variant="footer">
                 {{ $t(link.name) }}
               </LinkBase>

Also applies to: 126-137

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/AppFooter.vue` around lines 13 - 16, The FooterLink union type
currently allows a { name: string; kbd: string; } variant that the template
never handles, causing kbd-only items to fall through to LinkBase with an
undefined to/href; update FooterLink and the template to be consistent: either
remove the kbd-only variant from the FooterLink union (leaving only link and
button shapes) and pass link.href directly to LinkBase, or if kbd entries are
intended, add a branch in the template that renders the kbd variant explicitly.
Locate the FooterLink type and the template rendering logic (references:
FooterLink, LinkBase, link.href, and any branch that checks link.type) and make
the type and rendering branches match so that all union variants are fully
handled and link.href is never undefined when passed to LinkBase.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/components/AppFooter.vue`:
- Around line 36-88: The footer column headings in footerSections are raw
English tokens ('resources', 'features', 'other') causing untranslated UI;
change the label values in the footerSections array to translation keys (e.g.
'footer.resources', 'footer.features', 'footer.other') and update the
AppFooter.vue render to call $t(...) for those labels (locate the footerSections
constant and where it's rendered in AppFooter.vue), then add matching entries in
the locale files for each supported language so the headings display localized
text.

---

Nitpick comments:
In `@app/components/AppFooter.vue`:
- Around line 13-16: The FooterLink union type currently allows a { name:
string; kbd: string; } variant that the template never handles, causing kbd-only
items to fall through to LinkBase with an undefined to/href; update FooterLink
and the template to be consistent: either remove the kbd-only variant from the
FooterLink union (leaving only link and button shapes) and pass link.href
directly to LinkBase, or if kbd entries are intended, add a branch in the
template that renders the kbd variant explicitly. Locate the FooterLink type and
the template rendering logic (references: FooterLink, LinkBase, link.href, and
any branch that checks link.type) and make the type and rendering branches match
so that all union variants are fully handled and link.href is never undefined
when passed to LinkBase.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 552cd807-7e96-4a4f-9fa7-000583bee3a6

📥 Commits

Reviewing files that changed from the base of the PR and between ded091f and 5ac9737.

📒 Files selected for processing (1)
  • app/components/AppFooter.vue

Comment thread app/components/AppFooter.vue
Copy link
Copy Markdown
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: 1

♻️ Duplicate comments (1)
app/components/AppFooter.vue (1)

38-40: ⚠️ Potential issue | 🟡 Minor

Localise the footer section headings.

resources, features, and other still render as raw English strings while the link labels use translation keys. Store heading translation keys and render them through $t(...).

Suggested change
-    label: 'resources',
+    label: 'footer.resources',
@@
-    label: 'features',
+    label: 'footer.features',
@@
-    label: 'other',
+    label: 'footer.other',
@@
-              {{ section.label }}
+              {{ $t(section.label) }}

Also applies to: 60-62, 77-79, 125-127

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/AppFooter.vue` around lines 38 - 40, The footer section
headings are hard-coded strings inside the const footerSections definition in
AppFooter.vue (labels 'resources', 'features', 'other'); change those label
entries to translation keys (e.g., 'footer.resources', 'footer.features',
'footer.other') and render them with $t(...) where the section label is
displayed (instead of printing the raw label), ensuring all occurrences
(including the other repeated blocks at the same pattern) use $t to localize the
headings consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/components/AppFooter.vue`:
- Around line 42-86: In AppFooter.vue update all internal link href strings in
the footer data (e.g., entries with name 'footer.blog', 'footer.about',
'a11y.footer_title', 'privacy_policy.title', 'shortcuts.compare',
'shortcuts.settings', 'footer.keyboard_shortcuts', 'pds.title', 'footer.docs',
etc.) to use absolute paths with a leading slash (e.g., 'blog' -> '/blog') so
they don't resolve relative on nested routes, keep external constants like
NPMX_DOCS_SITE unchanged, and in the template replace the optional chaining
:to="link?.href" with a direct binding :to="link.href" (or the appropriate prop
name used by your router/link component) to rely on the v-if/v-else branch
guarantees.

---

Duplicate comments:
In `@app/components/AppFooter.vue`:
- Around line 38-40: The footer section headings are hard-coded strings inside
the const footerSections definition in AppFooter.vue (labels 'resources',
'features', 'other'); change those label entries to translation keys (e.g.,
'footer.resources', 'footer.features', 'footer.other') and render them with
$t(...) where the section label is displayed (instead of printing the raw
label), ensuring all occurrences (including the other repeated blocks at the
same pattern) use $t to localize the headings consistently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 49708c31-840a-4469-b814-3451ef99e12f

📥 Commits

Reviewing files that changed from the base of the PR and between 5ac9737 and b307347.

📒 Files selected for processing (1)
  • app/components/AppFooter.vue

Comment thread app/components/AppFooter.vue
Comment thread app/components/AppFooter.vue Outdated
Comment thread app/components/AppFooter.vue Outdated
Comment thread app/components/Link/Base.vue Outdated
Comment thread app/components/AppFooter.vue Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 22, 2026

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
i18n/locales/en.json Source changed, localizations will be marked as outdated.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

Copy link
Copy Markdown
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: 17

Caution

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

⚠️ Outside diff range comments (5)
i18n/locales/az-AZ.json (1)

23-49: ⚠️ Potential issue | 🟡 Minor

Remove sentinel copy from the Azerbaijani locale.

This commit populates many user-facing keys with EN TEXT TO REPLACE:. Since the keys exist, users will see the sentinel text and the normal missing-translation path will not apply. Prefer translating these values, or leaving unready keys absent/automation-managed until translations are available. Based on learnings, new or changed entries in non-English i18n files may be omitted because translations are handled separately.

Also applies to: 86-192, 214-214, 257-288, 333-349, 389-391, 430-458, 520-521, 536-595, 620-631, 661-691, 707-707, 783-784, 968-993, 1055-1083, 1231-1253, 1265-1273, 1287-1364, 1389-1434, 1575-1687

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@i18n/locales/az-AZ.json` around lines 23 - 49, The Azerbaijani locale
contains sentinel strings prefixed with "EN TEXT TO REPLACE:" that should not be
shipped; locate and remove or replace these values for keys shown in the diff
(e.g., "brand", "resources", "features", "other", "shortcuts.ctrl_key",
"shortcuts.command_palette", "shortcuts.command_palette_description",
"shortcuts.open_main", "shortcuts.open_diff", "shortcuts.open_timeline") and for
the other ranges listed in the comment, and either (a) provide the proper
Azerbaijani translation for each key or (b) remove the key entirely so the
normal missing-translation fallback applies; ensure you do not change keys
themselves, only replace or delete the sentinel string values.
i18n/locales/ar.json (1)

16-1687: ⚠️ Potential issue | 🟡 Minor

Remove the visible English placeholder markers from Arabic strings.

These are real locale values, so selecting Arabic can surface EN TEXT TO REPLACE: directly in the UI. Please either translate these entries or omit the untranslated string keys so the normal missing-translation flow can handle them.

Based on learnings: new or changed entries in i18n translation files may be omitted from non-English languages, and translations are tracked elsewhere.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@i18n/locales/ar.json` around lines 16 - 1687, The Arabic locale contains
visible English placeholder markers ("EN TEXT TO REPLACE:") in many translation
values (e.g., keys like "blog", "builders_chat", "brand", "resources",
"features", "other", "ctrl_key", "command_palette" and many nested entries under
"command_palette", "search", "settings", etc.); remove these markers by either
providing proper Arabic translations for those keys or deleting the untranslated
keys so the missing-translation fallback will apply; ensure you update or remove
every value that begins with "EN TEXT TO REPLACE:" across the keys referenced
(including top-level sections like "blog", "command_palette",
"translation_status", "brand", "compare", and any "EN TEXT TO REPLACE:" entries
in nested objects) so no English placeholder text appears to end users.
i18n/locales/it-IT.json (1)

16-1687: ⚠️ Potential issue | 🟡 Minor

Remove or translate visible EN TEXT TO REPLACE: placeholder strings.

The Italian locale file contains many string values with the literal EN TEXT TO REPLACE: marker. When rendered through the translation system, these will appear to users as untranslated placeholder text instead of either a proper translation or a fallback to English.

For non-English locale files, follow your project's convention: either provide actual translations, or omit untranslated keys entirely so the system falls back to the English version. Leaving literal placeholders in place defeats both purposes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@i18n/locales/it-IT.json` around lines 16 - 1687, The file contains many
literal "EN TEXT TO REPLACE:" placeholders (e.g. keys under "blog",
"shortcuts.ctrl_key", "command_palette", "settings.instant_search",
"package.links", "compare", "filters.view_selected", "code.copy_content",
"about.team", "brand", and other keys) that will surface to users; for each
occurrence either replace the "EN TEXT TO REPLACE:" prefixed value with a proper
Italian translation or remove the key entirely so the i18n system falls back to
English per project convention; search the JSON for the exact string "EN TEXT TO
REPLACE:" and update those values (or delete the key) across sections like
"command_palette", "trends", "compare", "pds", "vacations", "action_bar",
"brand", etc., ensuring pluralization/format placeholders
({name},{count},{ctrlKey}) are preserved.
i18n/locales/pl-PL.json (1)

23-49: ⚠️ Potential issue | 🟠 Major

Do not ship EN TEXT TO REPLACE: as Polish locale copy.

These markers will be displayed in Polish UI surfaces, including navigation, command palette, settings, package details, charts, translation status, brand pages, and accessibility labels. Use the existing missing/fallback translation workflow or plain English fallback text without the marker prefix. Based on learnings: new or changed entries in i18n translation files may be omitted from non-English languages, and translations are not completed in-band in the same PR.

Also applies to: 86-192, 214-214, 257-288, 342-349, 389-391, 430-458, 489-489, 520-620, 623-631, 691-707, 782-784, 968-993, 1055-1083, 1231-1253, 1264-1273, 1287-1290, 1354-1364, 1389-1434, 1575-1687

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@i18n/locales/pl-PL.json` around lines 23 - 49, Several Polish locale entries
(e.g., keys "brand", "resources", "features", "other", "ctrl_key",
"command_palette", "command_palette_description", "open_main", "open_diff",
"open_timeline") still contain the literal marker "EN TEXT TO REPLACE:" which
must not be shipped; remove that marker and replace each value with either the
proper Polish translation or a plain English fallback string (without the marker
prefix) and, if uncertain, revert to the existing missing/fallback translation
workflow so the UI shows the correct fallback rather than the marker text.
i18n/locales/uk-UA.json (1)

23-49: ⚠️ Potential issue | 🟠 Major

Remove the literal EN TEXT TO REPLACE: prefixes from Ukrainian UI strings.

These values will surface directly in the Ukrainian UI across the footer, command palette, package views, charts, code browser, and alt text. If translations are not ready, prefer the project’s fallback/missing-translation flow or plain English fallback text without the marker prefix. Based on learnings: new or changed entries in i18n translation files may be omitted from non-English languages, and translations are not completed in-band in the same PR.

Also applies to: 86-192, 268-288, 342-349, 389-391, 442-489, 568-584, 629-631, 968-973, 1251-1273, 1354-1364, 1687-1687

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@i18n/locales/uk-UA.json` around lines 23 - 49, Remove the literal "EN TEXT TO
REPLACE:" prefix from the Ukrainian translation values (e.g., keys "resources",
"features", "other", "ctrl_key", "command_palette",
"command_palette_description", "open_timeline" in uk-UA.json) so the UI won't
show the marker; if a true Ukrainian translation isn't available, replace the
value with plain English fallback text (without the prefix) or leave the key
absent so the app's missing-translation fallback is used, ensuring no marker
strings remain in any affected keys listed in the comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/components/AppFooter.vue`:
- Around line 107-113: The NuxtLink rendering social links (inside
AppFooter.vue, the v-for over socialLinks) uses target="_blank" but lacks a rel
attribute; update the NuxtLink element that iterates over socialLinks to include
rel="noopener noreferrer" (so each generated link includes rel when
target="_blank") to prevent opener exposure and reduce referrer leakage.

In `@i18n/locales/cs-CZ.json`:
- Around line 24-26: The Czech locale contains placeholder English strings for
the keys "resources", "features", and "other" (and other changed entries
referenced in the review); replace these placeholders with proper Czech
translations or temporarily remove the untranslated keys from the cs-CZ JSON so
the UI doesn't render "EN TEXT TO REPLACE: ..."; locate the keys (e.g.,
"resources", "features", "other" and the other changed entries listed) in the
cs-CZ locale file and either supply the correct Czech text or delete those
key/value pairs until a tracked translation is available.

In `@i18n/locales/de.json`:
- Around line 24-26: Replace all placeholder sentinel values that begin with "EN
TEXT TO REPLACE:" in the German locale file; specifically update the keys
"resources", "features", and "other" to remove the sentinel and provide proper
German translations (or plain English fallback text without the sentinel) and
then scan the file for the other occurrences called out (lines around 49, 288,
389-391, 442, 489, 569-583, 1265-1273, 1355-1364) and replace each "EN TEXT TO
REPLACE: ..." value with an appropriate German string (or plain English without
the sentinel) so no UI-facing entries contain the sentinel prefix.

In `@i18n/locales/hi-IN.json`:
- Around line 23-26: The hi-IN locale file contains placeholder values like "EN
TEXT TO REPLACE: brand", "EN TEXT TO REPLACE: Resources", "EN TEXT TO REPLACE:
Features", and "EN TEXT TO REPLACE: Other" (JSON keys: "brand", "resources",
"features", "other"); replace each placeholder with the correct Hindi
translation or remove the key entirely so the app falls back to the English
locale. Ensure you update every occurrence of the "EN TEXT TO REPLACE:" pattern
in hi-IN.json (not just the four shown) and keep the JSON keys unchanged while
providing proper Unicode-escaped or UTF-8 Hindi strings to avoid encoding
issues.

In `@i18n/locales/hu-HU.json`:
- Around line 16-26: Replace the placeholder "EN TEXT TO REPLACE:" values in the
Hungarian locale by either adding proper Hungarian translations or removing the
keys so the app falls back to the default locale; specifically update the
entries for "blog", "builders_chat", "brand", "resources", "features", and
"other" to real Hungarian strings (or delete them if translations are tracked
elsewhere) to avoid shipping English placeholder text in hu-HU.json.
- Line 1587: The "missing_keys" translation dropped the {count} token in its
plural forms so the UI cannot show how many translations are missing; update the
"missing_keys" value (the key "missing_keys") to include the {count} placeholder
in the plural segment(s) while preserving the plural form separators (e.g.,
singular|plural or the existing pipes) so the pluralization system receives the
count token (ensure {count} appears in the appropriate plural variants).

In `@i18n/locales/id-ID.json`:
- Around line 24-26: Replace the visible placeholder prefix "EN TEXT TO
REPLACE:" in the Indonesian locale entries by providing proper translations or
safe English fallbacks for the affected keys (e.g., "resources", "features",
"other" and all other keys flagged in the comment ranges), i.e., remove the
literal prefix and update each value to a translated Indonesian string or an
unsuffixed English fallback (or delete the key if you intend to rely on fallback
behavior); ensure you apply this change consistently for the other listed keys
so no runtime UI strings contain the "EN TEXT TO REPLACE:" prefix.

In `@i18n/locales/kn-IN.json`:
- Line 1587: The "missing_keys" translation currently drops the {count}
placeholder in plural forms; update the value for the missing_keys key so it
uses a plural-aware message that preserves {count} (or #) in the one/other
variants and includes a zero/no-missing variant, e.g. use an ICU-style plural
string that keeps {count} (or #) in the singular and plural branches and a
distinct message for zero.
- Around line 16-26: Replace or remove the placeholder English prefix "EN TEXT
TO REPLACE:" from the affected locale values so the Kannada UI doesn't show the
marker; for keys blog, builders_chat, keyboard_shortcuts, brand, resources,
features, and other either provide proper Kannada translations for their values
or remove those entries so the app falls back to the default/missing-translation
workflow instead of committing the placeholder text. Ensure you update only the
value strings (not the keys) in the kn-IN.json entries to a real Kannada string
or delete the key entirely if translations are tracked elsewhere.

In `@i18n/locales/mr-IN.json`:
- Around line 23-49: The JSON contains untranslated sentinel values "EN TEXT TO
REPLACE" for many locale keys (e.g., "brand", "resources",
"shortcuts.section.global", "shortcuts.command_palette",
"shortcuts.command_palette_description", "shortcuts.disable_shortcuts", etc.)
which will surface in the Marathi UI; remove or replace these sentinel strings
with proper Marathi translations or revert the keys to be omitted/managed by the
localization automation for now. Locate the keys in i18n/locales/mr-IN.json
(search for the strings "EN TEXT TO REPLACE" or the specific keys above), and
either (a) provide accurate Marathi translations for each key, or (b) remove
those key-value pairs so the automation/fallback can handle them, ensuring you
do the same for the other ranges called out (lines referenced in the review) to
avoid committing untranslated placeholders.

In `@i18n/locales/nb-NO.json`:
- Around line 24-26: Replace the placeholder English labels in nb-NO locale by
either providing proper Norwegian translations for the keys "resources",
"features", and "other" (and any other entries flagged in the review such as
those around lines referenced) or remove the unused keys so the
missing-translation workflow handles them; update the JSON entries in
i18n/locales/nb-NO.json for the specific keys ("resources", "features", "other"
and the other noted keys) to their Norwegian equivalents (or delete the keys)
ensuring valid JSON syntax is preserved.

In `@i18n/locales/nl.json`:
- Around line 24-26: Remove the literal prefix "EN TEXT TO REPLACE: " from Dutch
user-facing values in nl.json (e.g., keys "resources", "features", "other" and
all other entries flagged in the comment ranges) so the UI won't display the
marker; for entries you don't have a Dutch translation for, replace the value
with plain English fallback text (without the marker) or leave the key to the
fallback/missing-translation mechanism, and ensure no occurrences of "EN TEXT TO
REPLACE:" remain anywhere in nl.json (check the specified ranges: 49, 288,
389-391, 442, 489, 568-584, 1265-1273, 1354-1364, 1466-1542, 1598-1627).

In `@i18n/locales/pt-BR.json`:
- Around line 24-26: In the pt-BR locale file remove the user-visible
placeholder "EN TEXT TO REPLACE:" strings so Portuguese users don't see English
markers: for each affected translation key (e.g., "resources", "features",
"other" and the other keys flagged in the review) either replace the value with
the correct Portuguese translation or delete the key entirely so the i18n
fallback returns the English source; ensure no values contain the literal
substring "EN TEXT TO REPLACE:" anywhere in i18n/locales/pt-BR.json.

In `@i18n/locales/sr-Latn-RS.json`:
- Around line 24-26: Replace the literal placeholder prefix "EN TEXT TO
REPLACE:" for the identified translation keys (e.g., "resources", "features",
"other") in i18n/locales/sr-Latn-RS.json by either providing proper Serbian
translations, removing the keys so the app can fall back to the default locale,
or replacing with plain English strings without the prefix; ensure you update
all occurrences listed in the comment (lines referenced) so no translation value
contains the "EN TEXT TO REPLACE:" marker before release.

In `@i18n/locales/vi-VN.json`:
- Around line 24-26: Several Vietnamese locale entries still contain the literal
marker "EN TEXT TO REPLACE:" which will render in the UI; for each affected key
(e.g., "resources", "features", "other" and the other keys listed in the
comment) remove the "EN TEXT TO REPLACE:" prefix and either replace the value
with a proper Vietnamese translation, replace it with plain English text without
the marker, or remove the key to allow English fallback; ensure you update every
occurrence mentioned (lines noted in the review) and keep the JSON valid (quotes
and commas intact).

In `@i18n/locales/zh-CN.json`:
- Around line 24-26: Replace the literal placeholder strings in the zh-CN locale
(the keys "resources", "features", and "other") with proper Chinese translations
or remove these entries so the app falls back to the default/missing-translation
flow; do the same for the other affected keys cited in the review (ensure you
don't leave "EN TEXT TO REPLACE: ..." strings in any non-English locale file),
and confirm the locale file validates after your edits.

In `@i18n/locales/zh-TW.json`:
- Around line 24-26: The zh-TW locale contains literal marker strings (e.g., the
keys "resources", "features", "other" in zh-TW.json and the other listed ranges)
that will show to users; replace these placeholder values with proper
Traditional Chinese translations or remove the keys so the app falls back to the
default locale instead of shipping "EN TEXT TO REPLACE: ...". Locate the entries
for "resources", "features", "other" (and the other referenced entries at the
noted ranges) in zh-TW.json, either provide the proper zh-TW translations for
each value or delete the keys entirely to rely on the
fallback/missing-translation behavior used elsewhere.

---

Outside diff comments:
In `@i18n/locales/ar.json`:
- Around line 16-1687: The Arabic locale contains visible English placeholder
markers ("EN TEXT TO REPLACE:") in many translation values (e.g., keys like
"blog", "builders_chat", "brand", "resources", "features", "other", "ctrl_key",
"command_palette" and many nested entries under "command_palette", "search",
"settings", etc.); remove these markers by either providing proper Arabic
translations for those keys or deleting the untranslated keys so the
missing-translation fallback will apply; ensure you update or remove every value
that begins with "EN TEXT TO REPLACE:" across the keys referenced (including
top-level sections like "blog", "command_palette", "translation_status",
"brand", "compare", and any "EN TEXT TO REPLACE:" entries in nested objects) so
no English placeholder text appears to end users.

In `@i18n/locales/az-AZ.json`:
- Around line 23-49: The Azerbaijani locale contains sentinel strings prefixed
with "EN TEXT TO REPLACE:" that should not be shipped; locate and remove or
replace these values for keys shown in the diff (e.g., "brand", "resources",
"features", "other", "shortcuts.ctrl_key", "shortcuts.command_palette",
"shortcuts.command_palette_description", "shortcuts.open_main",
"shortcuts.open_diff", "shortcuts.open_timeline") and for the other ranges
listed in the comment, and either (a) provide the proper Azerbaijani translation
for each key or (b) remove the key entirely so the normal missing-translation
fallback applies; ensure you do not change keys themselves, only replace or
delete the sentinel string values.

In `@i18n/locales/it-IT.json`:
- Around line 16-1687: The file contains many literal "EN TEXT TO REPLACE:"
placeholders (e.g. keys under "blog", "shortcuts.ctrl_key", "command_palette",
"settings.instant_search", "package.links", "compare", "filters.view_selected",
"code.copy_content", "about.team", "brand", and other keys) that will surface to
users; for each occurrence either replace the "EN TEXT TO REPLACE:" prefixed
value with a proper Italian translation or remove the key entirely so the i18n
system falls back to English per project convention; search the JSON for the
exact string "EN TEXT TO REPLACE:" and update those values (or delete the key)
across sections like "command_palette", "trends", "compare", "pds", "vacations",
"action_bar", "brand", etc., ensuring pluralization/format placeholders
({name},{count},{ctrlKey}) are preserved.

In `@i18n/locales/pl-PL.json`:
- Around line 23-49: Several Polish locale entries (e.g., keys "brand",
"resources", "features", "other", "ctrl_key", "command_palette",
"command_palette_description", "open_main", "open_diff", "open_timeline") still
contain the literal marker "EN TEXT TO REPLACE:" which must not be shipped;
remove that marker and replace each value with either the proper Polish
translation or a plain English fallback string (without the marker prefix) and,
if uncertain, revert to the existing missing/fallback translation workflow so
the UI shows the correct fallback rather than the marker text.

In `@i18n/locales/uk-UA.json`:
- Around line 23-49: Remove the literal "EN TEXT TO REPLACE:" prefix from the
Ukrainian translation values (e.g., keys "resources", "features", "other",
"ctrl_key", "command_palette", "command_palette_description", "open_timeline" in
uk-UA.json) so the UI won't show the marker; if a true Ukrainian translation
isn't available, replace the value with plain English fallback text (without the
prefix) or leave the key absent so the app's missing-translation fallback is
used, ensuring no marker strings remain in any affected keys listed in the
comment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 006b9a9d-c259-4d3c-9f3d-29c49728db14

📥 Commits

Reviewing files that changed from the base of the PR and between b307347 and 205054b.

📒 Files selected for processing (32)
  • app/components/AppFooter.vue
  • i18n/locales/ar.json
  • i18n/locales/az-AZ.json
  • i18n/locales/bg-BG.json
  • i18n/locales/bn-IN.json
  • i18n/locales/cs-CZ.json
  • i18n/locales/de.json
  • i18n/locales/en.json
  • i18n/locales/es.json
  • i18n/locales/fr-FR.json
  • i18n/locales/hi-IN.json
  • i18n/locales/hu-HU.json
  • i18n/locales/id-ID.json
  • i18n/locales/it-IT.json
  • i18n/locales/ja-JP.json
  • i18n/locales/kn-IN.json
  • i18n/locales/mr-IN.json
  • i18n/locales/nb-NO.json
  • i18n/locales/ne-NP.json
  • i18n/locales/nl.json
  • i18n/locales/pl-PL.json
  • i18n/locales/pt-BR.json
  • i18n/locales/ru-RU.json
  • i18n/locales/sr-Latn-RS.json
  • i18n/locales/ta-IN.json
  • i18n/locales/te-IN.json
  • i18n/locales/tr-TR.json
  • i18n/locales/uk-UA.json
  • i18n/locales/vi-VN.json
  • i18n/locales/zh-CN.json
  • i18n/locales/zh-TW.json
  • i18n/schema.json
✅ Files skipped from review due to trivial changes (1)
  • i18n/locales/en.json

Comment thread app/components/AppFooter.vue
Comment thread i18n/locales/cs-CZ.json Outdated
Comment thread i18n/locales/de.json Outdated
Comment thread i18n/locales/hi-IN.json Outdated
Comment thread i18n/locales/hu-HU.json Outdated
Comment thread i18n/locales/pt-BR.json Outdated
Comment thread i18n/locales/sr-Latn-RS.json Outdated
Comment thread i18n/locales/vi-VN.json Outdated
Comment thread i18n/locales/zh-CN.json Outdated
Comment thread i18n/locales/zh-TW.json Outdated
@j0u1 j0u1 requested a review from alexdln April 22, 2026 13:10
@alexdln alexdln added this pull request to the merge queue Apr 22, 2026
Merged via the queue into npmx-dev:main with commit 8372d67 Apr 22, 2026
19 checks passed
@github-actions
Copy link
Copy Markdown

Thanks for your first contribution, @j0u1! 💫

We'd love to welcome you to the npmx community. Come and say hi on Discord! And once you've joined, visit npmx.wamellow.com to claim the contributor role.

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