diff --git a/.changeset/eighty-bears-yawn.md b/.changeset/eighty-bears-yawn.md new file mode 100644 index 0000000..d1c219f --- /dev/null +++ b/.changeset/eighty-bears-yawn.md @@ -0,0 +1,5 @@ +--- +"drupal-remix": major +--- + +Updates the shape of the meta tags, and support multiple replace diff --git a/packages/drupal-remix/README.md b/packages/drupal-remix/README.md index 6c7667c..87120d7 100644 --- a/packages/drupal-remix/README.md +++ b/packages/drupal-remix/README.md @@ -4,7 +4,7 @@ A list of utilities to help you integrate your Drupal site with Remix. ## Prerequisites -Make sure your Drupal site is using the [Metatag](https://www.drupal.org/project/metatag), [GraphQL Compose](https://www.drupal.org/project/graphql_compose) and [Remix](https://www.drupal.org/project/remix) modules. +Make sure your Drupal site is using the [Metatag](https://www.drupal.org/project/metatag), and [GraphQL Compose](https://www.drupal.org/project/graphql_compose) modules. ## Usage of Metatags helper @@ -30,39 +30,30 @@ export const meta: MetaFunction = ({ ### Overriding values (optional) -You can override specific values in the meta tags by providing a metaTagOverrides object to the metaTags function. This object consists of three keys: MetaTagLink, MetaTagProperty, and MetaTagValue. Each key corresponds to a specific kind of meta tag. - -MetaTagLink Overrides -To override the `` tag with the canonical attribute, use the MetaTagLink key. For example: +You can override specific values in the meta tags by providing a metaTagOverrides object to the metaTags function. This object consists of three keys: MetaTagLink, MetaTagProperty, and MetaTagValue. Each key corresponds to a specific kind of meta tag and you can set the overrides for each key as needed. ```typescript -export const meta: MetaFunction = ({ - data, -}: { - data: { node: { metatag } }; -}) => { - return metaTags({ - tags: data.node.metatag, - metaTagOverrides: { - MetaTagLink: { - canonical: { - kind: "replace", - pattern: "drupal-api-url.pantheonsite.io", - replacement: "drupal-site.pages.dev", - }, - }, +return metaTags({ + tags: data.node.metatag, + metaTagOverrides: { + MetaTagLink: { + ... }, - }); -}; + MetaTagProperty: { + ... + }, + MetaTagValue: { + ... + }, + }, +}); ``` -In this example, the canonical attribute of the `` tag will be overridden. The kind property determines the type of override to perform. The available options are: +There is two ways to override the values, one is fully overriding the value with the provided replacement, and the other is searching and replacing a specific pattern within the value. -- "replace": Replaces a specific pattern within the value with the provided replacement. -- "override": Fully replaces the value with the provided replacement. +#### Override -MetaTagProperty Overrides -To override a `` tag with the property attribute, use the MetaTagProperty key. For example: +To fully override the value with a desired value, you can pass the desired value as string to the replacement key. For example, to override the `canonical` attribute of the `` tag, use the MetaTagLink key. ```typescript export const meta: MetaFunction = ({ @@ -73,22 +64,31 @@ export const meta: MetaFunction = ({ return metaTags({ tags: data.node.metatag, metaTagOverrides: { - MetaTagProperty: { - "og:url": { - kind: "replace", - pattern: "drupal-api-url.pantheonsite.io", - replacement: "drupal-site.pages.dev", - }, + MetaTagLink: { + canonical: "https://your-site-url.com", }, }, }); }; ``` -In this example, the `` tag with the property attribute set to "og:url" will be overridden. The kind property determines the type of override to perform. +It will produce the following output in the HTML: -MetaTagValue Overrides -To override a `` tag with the name attribute, use the MetaTagValue key. For example: +```html +
+ + + + +``` + +Ignoring the original value of the `canonical` attribute. + +#### Search and Replace + +To search and replace a specific pattern within the value, you can pass an array of objects that contains the `pattern` and `replacement` keys. It allows you to add multiple search and replace operations to the same value. For example, replace the domain name in the `canonical` attribute of the `` tag. + +It is useful when you want to replace the Drupal site URL with the Remix site URL. ```typescript export const meta: MetaFunction = ({ @@ -99,96 +99,30 @@ export const meta: MetaFunction = ({ return metaTags({ tags: data.node.metatag, metaTagOverrides: { - MetaTagValue: { - "twitter:url": { - kind: "replace", - pattern: "drupal-api-url.pantheonsite.io", - replacement: "drupal-site.pages.dev", - }, + MetaTagLink: { + canonical: [ + { + pattern: "drupal-site-url.com", + replacement: "your-site-url.com", + }, + ], }, }, }); }; ``` -In this example, the `` tag with the name attribute set to "twitter:url" will be overridden. The kind property determines the type of override to perform. - -The available kind options for MetaTagProperty and MetaTagValue are the same as mentioned earlier: "replace" and "override". - -## Fetching data form Drupal using GraphQL - -```typescript -export const loader = async ({ params, context, request }: LoaderFunctionArgs) => { - const path = calculatePath({path: params["*"], url: request.url}); - const client = await getClient({ - url: context.cloudflare.env.DRUPAL_GRAPHQL_URI, - auth: { - uri: context.cloudflare.env.DRUPAL_AUTH_URI, - clientId: context.cloudflare.env.DRUPAL_CLIENT_ID, - clientSecret: context.cloudflare.env.DRUPAL_CLIENT_SECRET, - }, - }); - - const nodeRouteQuery = graphql(` - query route ($path: String!){ - route(path: $path) { - __typename - ... on RouteInternal { - entity { - __typename - ... on NodePage { - title - metatag { - __typename - ... on MetaTagLink { - attributes { - rel - href - } - } - ... on MetaTagValue { - attributes { - name - content - } - } - ... on MetaTagProperty { - attributes { - property - content - } - } - } - } - } - } - } - }`) - - const { data, error } = await client.query( - nodeRouteQuery, - { - path, - } - ); - - if (error) { - throw error; - } - - if (!data || !data?.route || data?.route.__typename !== "RouteInternal" || !data.route.entity) { - return redirect("/404"); - } +It will produce the following output in the HTML: - return json({ - type: data.route.entity.__typename, - node: data.route.entity, - environment: context.cloudflare.env.ENVIRONMENT, - }) -} +```html + + + + + ``` -> NOTE: This example is using Cloudflare and taking advantage of Environemt Settings to define "environment" key/value, that is why we are using the `context.cloudflare.env.ENVIRONMENT` object to obtain the value and pass it from Server to Client. +and will respect the original path. For example, if the original path was `https://drupal-site-url.com/path/to/page`, it will be replaced with `https://your-site-url.com/path/to/page`. ## Supporting organizations diff --git a/packages/drupal-remix/src/seo.ts b/packages/drupal-remix/src/seo.ts index 864d645..f2cc03e 100644 --- a/packages/drupal-remix/src/seo.ts +++ b/packages/drupal-remix/src/seo.ts @@ -1,23 +1,30 @@ // Keep in sync with the types in Remix MetaTags -type MetaDescriptor = { - charSet: "utf-8"; -} | { - title: string; -} | { - name: string; - content: string; -} | { - property: string; - content: string; -} | { - httpEquiv: string; - content: string; -} | { - [name: string]: string; - tagName: "meta" | "link"; -} | { - [name: string]: unknown; -} +type MetaDescriptor = + | { + charSet: "utf-8"; + } + | { + title: string; + } + | { + name: string; + content: string; + } + | { + property: string; + content: string; + } + | { + httpEquiv: string; + content: string; + } + | { + [name: string]: string; + tagName: "meta" | "link"; + } + | { + [name: string]: unknown; + }; type MetaTagUnion = (MetaTagLink | MetaTagValue | MetaTagProperty) & { __isUnion?: true; @@ -28,7 +35,7 @@ interface MetaTagLink { __typename: "MetaTagLink"; } -export type MetaTag = (MetaTagLink | MetaTagValue | MetaTagProperty) +export type MetaTag = MetaTagLink | MetaTagValue | MetaTagProperty; interface MetaTagLinkAttributes { rel?: string | null; @@ -55,13 +62,12 @@ interface MetaTagPropertyAttributes { content?: string | null; } -type OverrideKind = "replace" | "override"; - -type OverrideOptions = { - kind: OverrideKind; - pattern?: string; +type OverrideOptionsReplace = { + pattern: string; replacement: string; -}; +}[]; + +type OverrideOptions = string | OverrideOptionsReplace; type MetaTagOverrides = { [key in MetaTagUnion["__typename"]]?: { @@ -74,6 +80,20 @@ const DEFAULT_TAGS = [ { name: "viewport", content: "width=device-width,initial-scale=1" }, ]; +const applyOverrides = ( + overrides: OverrideOptions, + initial: string | null | undefined +) => { + if (typeof overrides === "string") { + return overrides; + } + + return overrides.reduce( + (acc, { pattern, replacement }) => acc?.replace(pattern, replacement), + initial + ); +}; + export const metaTags = ({ tags, defaultTags = [], @@ -102,10 +122,7 @@ export const metaTags = ({ }; } - const { kind, pattern, replacement } = willOverrideTag; - - const hrefOverride = - kind === "override" ? replacement : href?.replace(pattern!, replacement); + const hrefOverride = applyOverrides(willOverrideTag, href); return { tagName: "link", @@ -123,12 +140,7 @@ export const metaTags = ({ }; } - const { kind, pattern, replacement } = willOverrideTag; - - const contentOverride = - kind === "override" - ? replacement - : content?.replace(pattern!, replacement); + const contentOverride = applyOverrides(willOverrideTag, content); return { property, @@ -146,12 +158,7 @@ export const metaTags = ({ }; } - const { kind, pattern, replacement } = willOverrideTag; - - const contentOverride = - kind === "override" - ? replacement - : content?.replace(pattern!, replacement); + const contentOverride = applyOverrides(willOverrideTag, content); return { name,