Skip to content

Commit

Permalink
✨ feat(drupal-remix) Add multiples overrides (#95)
Browse files Browse the repository at this point in the history
* ✨ feat(drupal-remix) Add multiples overrides

* 📝 feat(drupal-remix) Update Readme
  • Loading branch information
enZane authored Aug 12, 2024
1 parent 07db8a7 commit 1a33ca5
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 159 deletions.
5 changes: 5 additions & 0 deletions .changeset/eighty-bears-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"drupal-remix": major
---

Updates the shape of the meta tags, and support multiple replace
168 changes: 51 additions & 117 deletions packages/drupal-remix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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 `<link>` 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 `<link>` 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 `<meta>` 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 `<link>` tag, use the MetaTagLink key.
```typescript
export const meta: MetaFunction = ({
Expand All @@ -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 `<meta>` 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 `<meta>` tag with the name attribute, use the MetaTagValue key. For example:
```html
<head>
<!-- Other meta tags -->
<link rel="canonical" href="https://your-site-url.com" />
<!-- Other meta tags -->
</head>
```
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 `<link>` tag.
It is useful when you want to replace the Drupal site URL with the Remix site URL.
```typescript
export const meta: MetaFunction = ({
Expand All @@ -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 `<meta>` 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
<head>
<!-- Other meta tags -->
<link rel="canonical" href="https://your-site-url.com" />
<!-- Other meta tags -->
</head>
```
> 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

Expand Down
91 changes: 49 additions & 42 deletions packages/drupal-remix/src/seo.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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"]]?: {
Expand All @@ -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 = [],
Expand Down Expand Up @@ -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",
Expand All @@ -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,
Expand All @@ -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,
Expand Down

0 comments on commit 1a33ca5

Please sign in to comment.