{"id":21956148,"url":"https://github.com/blankeos/vike-metadata","last_synced_at":"2026-02-03T12:12:33.893Z","repository":{"id":265113007,"uuid":"895167605","full_name":"Blankeos/vike-metadata","owner":"Blankeos","description":"🪝 A hook to manage metadata for your Vike apps.","archived":false,"fork":false,"pushed_at":"2024-12-09T06:10:52.000Z","size":287,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-27T23:18:40.328Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Blankeos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-27T17:21:16.000Z","updated_at":"2024-12-21T10:56:01.000Z","dependencies_parsed_at":"2024-12-04T21:29:10.552Z","dependency_job_id":null,"html_url":"https://github.com/Blankeos/vike-metadata","commit_stats":null,"previous_names":["blankeos/vike-metadata"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blankeos%2Fvike-metadata","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blankeos%2Fvike-metadata/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blankeos%2Fvike-metadata/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blankeos%2Fvike-metadata/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Blankeos","download_url":"https://codeload.github.com/Blankeos/vike-metadata/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235936115,"owners_count":19068830,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-29T08:20:00.470Z","updated_at":"2026-02-03T12:12:33.881Z","avatar_url":"https://github.com/Blankeos.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vike-metadata\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"_docs/image.png\" alt=\"vike-metadata-banner\" /\u003e\n\u003c/div\u003e\n\n\u003cdiv\u003e\n  \u003ctable\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\"\u003e\n      React\n      \u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\n      Solid\n      \u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\n      Vue\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\"\u003e\n        \u003ca href=\"https://www.npmjs.com/package/vike-metadata-react\" target=\"_blank\"\u003e\n          \u003cimg src=\"https://img.shields.io/npm/dw/vike-metadata-react?style=for-the-badge\u0026label=Downloads%20\" alt=\"NPM Downloads\"\u003e\u003c/img\u003e\u003c/a\u003e\n        \u003cimg src=\"https://deno.bundlejs.com/badge?q=vike-metadata-react\u0026badge-style=for-the-badge\u0026treeshake=\" alt=\"NPM Bundle Size\" \u003e\u003c/img\u003e\n      \u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\n        \u003ca href=\"https://www.npmjs.com/package/vike-metadata-solid\" target=\"_blank\"\u003e\n          \u003cimg src=\"https://img.shields.io/npm/dw/vike-metadata-solid?style=for-the-badge\u0026label=Downloads%20\" alt=\"NPM Downloads\"\u003e\u003c/img\u003e\u003c/a\u003e\n        \u003cimg src=\"https://deno.bundlejs.com/badge?q=vike-metadata-solid\u0026badge-style=for-the-badge\u0026treeshake=\" alt=\"NPM Bundle Size\" \u003e\u003c/img\u003e\n      \u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\n        \u003ca href=\"https://www.npmjs.com/package/vike-metadata-vue\" target=\"_blank\"\u003e\n          \u003cimg src=\"https://img.shields.io/npm/dw/vike-metadata-vue?style=for-the-badge\u0026label=Downloads%20\" alt=\"NPM Downloads\"\u003e\u003c/img\u003e\u003c/a\u003e\n        \u003cimg src=\"https://deno.bundlejs.com/badge?q=vike-metadata-vue\u0026badge-style=for-the-badge\u0026treeshake=\" alt=\"NPM Bundle Size\" \u003e\u003c/img\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003ctable\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/maintained%20with-bun-cc00ff.svg?style=for-the-badge\u0026logo=bun)](https://bun.sh/\" alt=\"Bun\"\u003e\u003c/img\u003e\n    \u003cimg src=\"https://img.shields.io/npm/l/vike-metadata-react?style=for-the-badge\" alt=\"NPM License\"\u003e\u003c/img\u003e\n\u003c/div\u003e\n\n🪝 A hook to manage metadata for your Vike + React/Solid/Vue app. Kinda like Next-SEO or React Helmet but for Vike and in a simple hook.\n\n## Features\n\n- [x] ☁️ Lightweight (minified \u0026 no extra dependencies).\n- [x] 😻 Typesafe, repeatable, and pleasant DX for managing meta tags.\n- [x] ❇️ Similar API to Next.js's [Metadata API](https://nextjs.org/docs/app/api-reference/functions/generate-metadata#metadata-object).\n- [x] ⚒️ Made for Vike + React/Solid/Vue.\n- [x] 🚀 Built on top of `useConfig` (a universal hook in Vike).\n\n## Quick start\n\nInstall it:\n\n```bash\nnpm i vike-metadata-react # react\nnpm i vike-metadata-solid # solid\nnpm i vike-metadata-vue # vue\n```\n\n### Get Started\n\n1. Configure defaults\n\n```tsx\n// In your app's entry point, usually layout.\nimport { useMetadata } from 'vike-metadata-solid';\n\nuseMetadata.setGlobalDefaults({\n  title: 'Vike + Solid',\n  description: 'Demo showcasing Vike + Solid',\n  viewport: {\n    width: 'device-width',\n    initialScale: 1,\n  },\n});\n\nexport function RootLayout(props) {\n  useMetadata({}); // Use at least once in layout, so all pages use it as default fallback.\n  // ...\n}\n```\n\n2. Use in your pages\n\nAdding defaults does not add the metadata to the page. But this part does. So if you don't use `useMetadata` on a page the tags will not be rendered at all. We don't use the cumulative approach like Next.js does.\n\n```tsx\nexport function Page() {\n  useMetadata({\n    title: getTitle('About'),\n    description: 'Learn about why this template is cool.',\n  });\n\n  // ...\n}\n```\n\n### FAQs\n\n- **It doesn't work on my Vike app.** Given that most Vike apps are built very granularly different from each other, you might have configured your app differently. `vike-metadata-*` expects the following practices if you choose to adopt this into your project:\n  - React|Vue|Solid: Must be using `vike-react` or `vike-vue` or `vike-solid`, custom vike plugins are not supported (yet).\n  - React|Vue|Solid: In `+config.ts`, do not use `Head` or `title`.\n  - React|Vue|Solid: Do not use `+Head.tsx` or `+title.ts` either.\n  - React: In `+config.ts`, `stream: true`.\n- **Is this a zero-cost abstraction?** Most abstractions aren't. This technically does parses the typescript data shape into actual metatags and a lot of IF statements to render them or not, so that might be the \"very, very\" small cost here? Obviously laying out your metatags by yourself would be computationally cheaper, but I haven't really tested the overhead. Although, I'd choose still this over laying it out myself just for the DX. In most cases, this is what Next.js's Metadata API does too.\n- **How to do Template Strings?** If you're looking for something like `%s | My Site`, just make a utility function like:\n\n  ```ts\n  const TITLE_TEMPLATE = '%s | My Site';\n  export function getTitle(title: string) {\n    return TITLE_TEMPLATE.replace('%s', title);\n  }\n  ```\n\n- **How to do dynamic meta tags (e.g. title)?** Just use `useData` or `usePageContext` along with `useMetadata`. For instance:\n\n  ```tsx\n  import { useMetadata } from 'vike-metadata-solid';\n  import { useData } from 'solid-start';\n\n  export function Page() {\n    const movie = useData\u003c{ title: string }\u003e();\n\n    useMetadata({\n      title: movie.title,\n    });\n\n    // ...\n  ```\n\n- **Gotcha: `@catchall` routes (Solid only).** In SolidJS apps, in catchall routes (`/*`) secifically, use `useMetadata(() =\u003e ({ ... }))` since the metadata depends on a signal (like the catchall slug), so the values stay reactive on the client and SSR can read the initial value. If not, the params you passed won't be reactive. You'd might be familiar with this behavior even with `@tanstack/solid-query`.\n\n  ```tsx\n  useMetadata(() =\u003e ({\n    title: `Catchall ${slug()}`,\n    description: 'Catchall example page',\n  }));\n  ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblankeos%2Fvike-metadata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblankeos%2Fvike-metadata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblankeos%2Fvike-metadata/lists"}