diff --git a/package-lock.json b/package-lock.json index 07d10b1..33aeee6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@forge42/seo-tools", - "version": "1.2.1", + "version": "1.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@forge42/seo-tools", - "version": "1.2.1", + "version": "1.3.1", "license": "MIT", "workspaces": [ ".", diff --git a/package.json b/package.json index 6a02f3d..af98e70 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@forge42/seo-tools", - "version": "1.3.0", + "version": "1.4.0", "private": false, "keywords": ["seo", "remix-seo", "seo-tools", "structured-data", "sitemap", "robots", "canonical", "seo-alternate"], "description": "Framework agnostic set of helpers designed to help you create, maintain and develop your SEO", diff --git a/src/remix/metadata.test.ts b/src/remix/metadata.test.ts new file mode 100644 index 0000000..7150b0c --- /dev/null +++ b/src/remix/metadata.test.ts @@ -0,0 +1,65 @@ +import { type MetaData, generateMeta } from "./metadata" + +describe("generateMeta suite", () => { + const baseMetaData: MetaData = { + title: "Test Page", + description: "This is a test page.", + url: "https://example.com", + image: "", + } + + const baseExpected = [ + { title: "Test Page" }, + { property: "og:title", content: "Test Page" }, + { property: "og:description", name: "description", content: "This is a test page." }, + { property: "og:url", content: "https://example.com" }, + { name: "twitter:card", property: "twitter:card", content: "summary_large_image" }, + ] + + it("generates meta tags with required fields", () => { + expect(generateMeta(baseMetaData)).toEqual(baseExpected) + }) + + it("includes og:image if image is provided", () => { + const metaData = { ...baseMetaData, image: "https://picsum.photos/200/300" } + expect(generateMeta(metaData)).toEqual([ + ...baseExpected, + { property: "og:image", content: "https://picsum.photos/200/300" }, + ]) + }) + + it("includes og:site_name if siteName is provided", () => { + const metaData = { ...baseMetaData, siteName: "Example Site" } + expect(generateMeta(metaData)).toEqual([...baseExpected, { name: "og:site_name", content: "Example Site" }]) + }) + + it("uses custom twitterCard if provided", () => { + const metaData = { ...baseMetaData, twitterCard: "summary" } + const expected = baseExpected.map((tag) => + tag.name === "twitter:card" ? { name: "twitter:card", property: "twitter:card", content: "summary" } : tag + ) + expect(generateMeta(metaData)).toEqual(expected) + }) + + it("includes additional meta descriptors", () => { + const metaData = { ...baseMetaData, image: "https://picsum.photos/200/300" } + const additional = [ + { property: "og:type", content: "website" }, + { name: "twitter:site", content: "@example" }, + ] + + expect(generateMeta(metaData, additional)).toEqual([ + ...baseExpected, + { property: "og:image", content: "https://picsum.photos/200/300" }, + ...additional, + ]) + }) + + it("handles empty additional data array", () => { + const metaData = { ...baseMetaData, image: "https://picsum.photos/200/300" } + expect(generateMeta(metaData, [])).toEqual([ + ...baseExpected, + { property: "og:image", content: "https://picsum.photos/200/300" }, + ]) + }) +}) diff --git a/src/remix/metadata.ts b/src/remix/metadata.ts index 91534a5..6df3e30 100644 --- a/src/remix/metadata.ts +++ b/src/remix/metadata.ts @@ -49,10 +49,6 @@ export interface MetaData { * this also generates the twitter:description and og:description meta tags. */ description: string - /** - * The keywords of the page. - */ - keywords?: string[] /** * The url of the page. * this generates the og:url meta tag. @@ -68,6 +64,13 @@ export interface MetaData { * this generates the og:site_name meta tag. */ siteName?: string + /** + * The twitter card type of the page. + * this generates the twitter:card meta tag. + * this is optional and will default to "summary_large_image". + * @default "summary_large_image" + */ + twitterCard?: string } /** * Generate meta tags for Remix to be consumed by the meta function. @@ -80,18 +83,15 @@ export interface MetaData { * @returns MetaDescriptor[] - Remix compatible meta tags */ export const generateMeta = (metaData: MetaData, additionalData?: MetaDescriptor[]) => { - const { title, description, url, siteName, image, keywords } = metaData + const { title, description, url, siteName, image, twitterCard = "summary_large_image" } = metaData return [ { title }, - { name: "twitter:title", content: title }, - { name: "og:title", content: title }, - { name: "description", content: description }, - { name: "twitter:description", content: description }, - { name: "og:description", content: description }, - { name: "og:url", content: url }, - ...(keywords ? [{ name: "keywords", content: keywords.join(", ") }] : []), + { property: "og:title", content: title }, + { property: "og:description", name: "description", content: description }, + { property: "og:url", content: url }, + { name: "twitter:card", property: "twitter:card", content: twitterCard }, ...(siteName ? [{ name: "og:site_name", content: siteName }] : []), - ...(image ? [{ name: "og:image", content: image }] : []), + ...(image ? [{ property: "og:image", content: image }] : []), ...(additionalData ?? []), ] } diff --git a/test-apps/remix-vite/app/routes/_index.tsx b/test-apps/remix-vite/app/routes/_index.tsx index 63e16e9..f5ad27a 100644 --- a/test-apps/remix-vite/app/routes/_index.tsx +++ b/test-apps/remix-vite/app/routes/_index.tsx @@ -9,6 +9,7 @@ export const meta: MetaFunction = () => { title: "test", description: "test", url: "test", + image: "https://picsum.photos/200/300", }, [ { "script:ld+json": article({