head (Next.js)
Converts a HeadDescriptor into a Next.js App Router Metadata object; part of the engine's experimental, unfinished Next.js adapter.
import { head } from '@salla.sa/twilight-theme-engine/nextjs';In plain words
A Next.js page describes its <head> by exporting metadata, or a generateMetadata() function that returns one. head(descriptor) from /nextjs converts the engine's HeadDescriptor into that object.
Salla themes run on TanStack Start. The /nextjs subpath is a start on Next.js support, and most of it is not built yet (see the notes).
Signature
function head(descriptor: HeadDescriptor): {
title?: string;
description?: string;
keywords?: string | string[];
robots?: string;
openGraph?: {
siteName?; type?; title?; description?; url?; locale?;
images?: Array<{ url: string; width?: number; height?: number; alt?: string }>;
publishedTime?; modifiedTime?;
};
twitter?: { card; title?; description?; images?: string[]; site?; creator? };
alternates: { canonical: string | undefined; languages: Record<string, string> | undefined };
}Try it live
HeadDescriptor through both adapters: a Next.js Metadata object on the left, TanStack head arrays on the right.Try this: turn on jsonLd and meta: they appear on the right only. The Next.js adapter has nowhere to put them and drops them./nextjs head(): {…} 6 keys
openGraph: {…} 9 keys
images: Array(1)
alternates: {…} 2 keys
languages: {…} 1 keys
/tanstack head(): {…} 4 keys
meta: Array(3)
0: {…} 1 keys
1: {…} 2 keys
2: {…} 2 keys
links: Array(2)
0: {…} 2 keys
1: {…} 3 keys
// app/new/page.tsx (Next.js App Router)
import { head } from '@salla.sa/twilight-theme-engine/nextjs';
export const metadata = head({
title: 'New arrivals',
description: 'Fresh arrivals every week',
canonical: 'https://example.com/ar/new',
alternateLanguages: [{ hreflang: 'en', href: 'https://example.com/en/new' }],
openGraph: { images: 'https://example.com/og.png' },
});
Example
import { head } from '@salla.sa/twilight-theme-engine/nextjs';
export const metadata = head({
title: 'Gift cards',
description: 'Send a gift card by email in a minute.',
alternateLanguages: [{ hreflang: 'en', href: '/en/gift-cards' }],
});
export default function GiftCardsPage() {
return <h1>Gift cards</h1>;
}
How it behaves
title,description,keywordsandrobotsare copied.openGraphandtwitterfall back to the top-level title and description, andtwitter.carddefaults tosummary_large_image.canonicalandalternateLanguagesbecomealternates.canonicalandalternates.languages({ en: href }).Status of
/nextjs:head,attrs,mergeAttrsandNextJsLinkAdapterare exported. There is no Next.js router, middleware or root route (src/nextjs/router.tsx is commented out),TwilightProviderhas no Next.js page-class sync, and the route modules' loaders and head functions read a twilight context that only the TanStack wiring fills.
Gotchas
Next.js metadata has no place for
jsonLd,meta,links,styles,scriptsorimportMap, nor foropenGraph.alternateLocaleandtwitter.url. They are dropped without a warning; render JSON-LD and scripts in the page instead.The JSDoc of src/nextjs/index.ts and docs/03-routing-system.md import
createRouterfrom/nextjsand callhead(Product.head(…))with one argument./nextjsexports nocreateRouter, and a route module'sheadtakes(ctx, data).
Related
Converts a HeadDescriptor (title, description, Open Graph, canonical, JSON-LD) into the meta, links, styles and scripts arrays a TanStack route returns.
attrs, mergeAttrs (Next.js)The Next.js copies of attrs and mergeAttrs: descriptors in, htmlAttrs and bodyAttrs out, for a root layout that cannot call hooks.
NextJsLinkAdapterThe link adapter for Next.js setups. It renders a plain anchor, not next/link, so a click loads a whole new page.