@nextyugai/ui-landing
v0.3.0
Published
The Nextyug landing design system: the Tailwind token layer and the server-rendered marketing components every Nextyug product site shares.
Maintainers
Readme
@nextyugai/ui-landing
The Nextyug landing design system: the Tailwind token layer and the server-rendered marketing components every Nextyug product site shares.
There are two design systems in this organisation and only two. This is the one
for marketing and landing pages. Admin consoles use @nextyugai/ui.
Install
npm i @nextyugai/ui-landing
npm i -D tailwindcss @tailwindcss/postcss// next.config.ts
transpilePackages: ['@nextyugai/ui-landing']/* app/globals.css */
@import "tailwindcss";
@import "@nextyugai/ui-landing/styles.css";Order matters: Tailwind first, then this. The stylesheet carries the brand
tokens, the @theme inline mapping that turns them into utilities, the base
layer, and an @source directive so Tailwind scans this package's own class
names — it does not scan node_modules on its own, and without that line the
components render unstyled.
Everything here is a server component
No 'use client', anywhere. That is the point of this package rather than a
convenience: a marketing page's job is to be fast and indexable, and one client
component pulls the React runtime into every route in the tree.
The consequences are deliberate:
Ctais a link, not a button. A call to action is a navigation.- The mobile menu is a
<details>. It works before any JavaScript arrives. CodeBlockis not syntax highlighted. Highlighting is a client or build-time dependency, and static blocks read fine in one colour.ThemeToggleholds no React state. The state is an attribute on<html>andlocalStorageremembers it. RenderTHEME_SCRIPTin<head>and the stored theme applies before the body paints, with no flash of the wrong one.
If your app has a check:no-client script, this package will not break it.
Use
import { Navbar, Footer, THEME_SCRIPT } from '@nextyugai/ui-landing'
const SITE = { name: 'Nextyug Identity', description: '…', org: 'Nextyug Technologies Pvt Ltd' }
const NAV = [{ href: '/pricing', label: 'Pricing' }]
const APP = { signIn: '/login', signUp: '/login' }
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<head><script dangerouslySetInnerHTML={{ __html: THEME_SCRIPT }} /></head>
<body>
<Navbar site={SITE} nav={NAV} app={APP} />
{children}
<Footer site={SITE} nav={NAV} app={APP} siblings={[]} />
</body>
</html>
)
}The nav and the product's identity are props. A header that knows one product's menu is a header only that product can use — which is how four repositories ended up with four of them.
What's in it
| Group | Exports |
|---|---|
| Layout | Navbar Footer ThemeToggle THEME_SCRIPT |
| Page | PageHero prose |
| Bits | SectionHead CodeBlock Chip KeyValue Cta |
| Util | cn |
| Types | NavLink SiteInfo AppLinks SiblingProduct |
prose is a class string for running text — the legal pages and About — rather
than the typography plugin, which would be a dependency for four pages.
What stays in each app
The logo (/logo.svg in your own public/), the nav and footer contents, page
copy, robots.ts, sitemap.ts and the OpenGraph image. Those are the product,
not the system.
Versioning
Semver from 0.1.0. On 0.x a token change is a minor bump; upgrade
deliberately.
