Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Last active December 3, 2025 08:27
Show Gist options
  • Select an option

  • Save ryanflorence/ec1849c6d690cfbffcb408ecd633e069 to your computer and use it in GitHub Desktop.

Select an option

Save ryanflorence/ec1849c6d690cfbffcb408ecd633e069 to your computer and use it in GitHub Desktop.
import type { V2_HtmlMetaDescriptor, V2_MetaFunction } from "@remix-run/node";
export const mergeMeta = (
overrideFn: V2_MetaFunction,
appendFn?: V2_MetaFunction,
): V2_MetaFunction => {
return arg => {
// get meta from parent routes
let mergedMeta = arg.matches.reduce((acc, match) => {
return acc.concat(match.meta || []);
}, [] as V2_HtmlMetaDescriptor[]);
// replace any parent meta with the same name or property with the override
let overrides = overrideFn(arg);
for (let override of overrides) {
let index = mergedMeta.findIndex(
meta =>
("name" in meta &&
"name" in override &&
meta.name === override.name) ||
("property" in meta &&
"property" in override &&
meta.property === override.property) ||
("title" in meta && "title" in override),
);
if (index !== -1) {
mergedMeta.splice(index, 1, override);
}
}
// append any additional meta
if (appendFn) {
mergedMeta = mergedMeta.concat(appendFn(arg));
}
return mergedMeta;
};
};
import { mergeMeta } from "./merge-meta";
export const meta = mergeMeta(
// these will override the parent meta
({ data }) => {
return [{ title: data.project.name }];
},
// these will be appended to the parent meta
({ matches }) => {
return [{ name: "author", content: "Ryan Florence" }];
},
);
// both functions get the same arguments as a normal meta function
@keul
Copy link

keul commented Dec 2, 2025

For posterities: to make TS to work with loaded data in <2 remix versions, I had to change the signature as follows:

export const mergeMeta = <
  Loader = unknown,
  ParentsLoaders extends Record<string, unknown> = Record<string, unknown>,
>(
  overrideFn: MetaFunction<Loader, ParentsLoaders>,
  appendFn?: MetaFunction<Loader, ParentsLoaders>,
): MetaFunction<Loader, ParentsLoaders> => {
  return (arg) => {
  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment