open-design/apps/landing-page/app/_components/site-footer.astro
Jane 3e0ff3d0fa
feat(landing-page): point catalog links at /plugins, drop legacy /skills /systems routes (#3386)
The 2026-05 plugins rebuild left three homepage/library surfaces still
pointing at the retired `/skills/`, `/systems/`, and `/craft/` route
trees, so visitors hit a 301 hop (or a stale facet) instead of landing
directly on the new `/plugins/*` pages. Repoint them at the canonical
destinations and align the homepage Labs pills with the real library.

- system-card: link straight to `/plugins/design-system-<slug>/` via a
  new `detailHrefForSystemSlug` resolver instead of hard-coding
  `/systems/<slug>/` and relying on the redirect. The ~8 systems that
  ship no manifest (hence no detail page) degrade to `/plugins/systems/`,
  the same destination the legacy 301 produced, minus the hop and with no
  risk of linking at a page that doesn't exist.
- homepage Labs pills: replace the hard-coded prototype/deck/mobile/office
  facets (mobile/office had drifted to stale or empty counts) with a live
  top-4 of `PLUGIN_CATEGORIES`, counted with the same `categorizePlugin`
  rule `/plugins/templates/` uses and labelled from `pcopy.category`, so
  the homepage stays in lockstep with the library and never shows a dead
  chip. Counts are surfaced through a new `CatalogCounts.templateCategories`.
- remove the Craft entry points from the homepage footer, sub-page footer,
  header Library dropdown, and the plugins hub tile grid. The `/craft/`
  pages stay live; they're just no longer surfaced in site chrome.

The legacy `/skills/`, `/systems/`, `/templates/` 301s added in the prior
PR stay in place for inbound links and search equity.

Co-authored-by: Joey-nexu <joeylee12629@gmail.com>
2026-05-31 11:53:36 +00:00

83 lines
3 KiB
Text

---
import type { HeaderProps } from './header';
import {
DEFAULT_LOCALE,
getCommonCopy,
getLandingUiCopy,
isLandingLocale,
localizedHref,
} from '../i18n';
interface Props {
counts: HeaderProps['counts'];
locale?: string;
}
const { counts, locale: rawLocale = DEFAULT_LOCALE } = Astro.props as Props;
const locale = isLandingLocale(rawLocale) ? rawLocale : DEFAULT_LOCALE;
const copy = getCommonCopy(locale).header;
const ui = getLandingUiCopy(locale);
const href = (path: string) => localizedHref(path, locale);
const REPO = 'https://github.com/nexu-io/open-design';
const DISCORD = 'https://discord.gg/9ptkbbqRu';
const X_TWITTER = 'https://x.com/nexudotio';
---
<footer class='sub-footer' data-od-id='sub-footer'>
<div class='container sub-footer-inner'>
<div class='sub-footer-grid'>
<div class='sub-footer-brand'>
<a href={href('/')} class='brand'>
<span class='brand-mark'>
<img src='/logo.webp' alt='' width='36' height='36' />
</span>
<span>Open Design</span>
</a>
<p>
{ui.footer.summary}
</p>
</div>
<div class='sub-footer-col'>
<h5>{ui.footer.products}</h5>
<ul>
<li><a href={href('/')}>Open Design</a></li>
<li><a href={href('/html-anything/')}>{ui.footer.htmlAnything}</a></li>
</ul>
</div>
<div class='sub-footer-col'>
<h5>{copy.nav.plugins}</h5>
<ul>
<li><a href={href('/plugins/templates/')}>{copy.nav.templates}</a></li>
<li><a href={href('/plugins/skills/')}>{copy.nav.skills}</a></li>
<li><a href={href('/plugins/systems/')}>{copy.nav.systems}</a></li>
</ul>
</div>
<div class='sub-footer-col'>
<h5>{ui.footer.resources}</h5>
<ul>
<li><a href={href('/official/')}>{ui.footer.official}</a></li>
<li><a href={href('/quickstart/')}>{ui.footer.quickstart}</a></li>
<li><a href={href('/agents/')}>{ui.footer.agents}</a></li>
<li><a href={href('/compare/')}>{ui.footer.compare}</a></li>
<li><a href={href('/alternatives/claude-design/')}>{ui.footer.claudeAlternative}</a></li>
</ul>
</div>
<div class='sub-footer-col'>
<h5>{ui.footer.connect}</h5>
<ul>
<li><a href={REPO} target='_blank' rel='noopener'>{ui.footer.github}</a></li>
<li><a href={`${REPO}/issues`} target='_blank' rel='noopener'>{ui.footer.issues}</a></li>
<li><a href={`${REPO}/releases`} target='_blank' rel='noopener'>{ui.footer.releases}</a></li>
<li><a href={DISCORD} target='_blank' rel='noopener'>{ui.footer.discord}</a></li>
<li><a href={X_TWITTER} target='_blank' rel='noopener'>{ui.footer.xTwitter}</a></li>
<li><a href='/blog/rss.xml'>{ui.footer.rss}</a></li>
<li><a href={href('/#contact')}>{copy.nav.contact}</a></li>
</ul>
</div>
</div>
<div class='sub-footer-bottom'>
<span>{ui.footer.bottomLeft}</span>
<span>{ui.footer.bottomRight}</span>
</div>
</div>
</footer>