Skip to content

Commit

Permalink
handle dynamic meta using Helmet component in search pages
Browse files Browse the repository at this point in the history
  • Loading branch information
enguerranws committed Oct 8, 2024
1 parent a88bd04 commit 0b3fd1e
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
import React from "react";
import { Helmet, HelmetProvider } from "react-helmet-async";
import { Helmet } from "react-helmet-async";
import {
MetaContentType,
adminMetaContent,
defaultMetaContents,
defaultPageMetaContents,
groupMetaContent,
metaContents,
standardMetaContent,
} from "src/app/contents/meta/metaContents";
import { StandardPageSlugs } from "src/app/routes/routeParams/standardPage";
import { routes, useRoute } from "src/app/routes/routes";
import { Route } from "type-route";

export const MetaContent = (): JSX.Element => {
export const DefaultMetaContent = (): JSX.Element => {
const route = useRoute();
const contents = getMetaContents(route);

return (
<HelmetProvider>
<Helmet>
<title>
{contents
? `${contents.title} - PMSMP: Immersion Facile`
: defaultMetaContents.title}
</title>
<meta
name="description"
content={
contents ? contents.description : defaultMetaContents.description
}
/>
</Helmet>
</HelmetProvider>
<Helmet>
<title>
{contents
? `${contents.title} - PMSMP: Immersion Facile`
: defaultMetaContents.title}
</title>
<meta
name="description"
content={
contents ? contents.description : defaultMetaContents.description
}
/>
</Helmet>
);
};

Expand All @@ -48,6 +46,6 @@ const getMetaContents = (
if (route.name === "admin") {
return adminMetaContent[route.params.tab];
}
return metaContents[route.name];
return defaultPageMetaContents[route.name];
}
};
4 changes: 3 additions & 1 deletion front/src/app/contents/meta/metaContents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export const defaultMetaContents: MetaContentType = {
description: "Faciliter la réalisation des immersions professionnelles.",
};

export const metaContents: Partial<Record<FrontRouteKeys, MetaContentType>> = {
export const defaultPageMetaContents: Partial<
Record<FrontRouteKeys, MetaContentType>
> = {
addAgency: {
title: "Formulaire d'ajout d'un prescripteur",
description: "Devenir prescripteur de PMSMP et immersions professionnelles",
Expand Down
13 changes: 8 additions & 5 deletions front/src/app/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import * as Sentry from "@sentry/browser";
import React from "react";
import { createRoot } from "react-dom/client";
import { ErrorBoundary } from "react-error-boundary";
import { HelmetProvider } from "react-helmet-async";
import { Provider } from "react-redux";
import { App } from "src/app/App";
import { MinimalErrorPage } from "src/app/pages/error/MinimalErrorPage";
import { store } from "src/config/dependencies";
import { ENV } from "src/config/environmentVariables";
import { MetaContent } from "./components/layout/MetaContent";
import { DefaultMetaContent } from "./components/layout/DefaultMetaContent";
import { RouteProvider } from "./routes/routes";

Sentry.init({
Expand All @@ -31,10 +32,12 @@ createRoot(rootContainer).render(
<ErrorBoundary
fallbackRender={({ error }) => <MinimalErrorPage error={error} />}
>
<RouteProvider>
<MetaContent />
<App />
</RouteProvider>
<HelmetProvider>
<RouteProvider>
<DefaultMetaContent />
<App />
</RouteProvider>
</HelmetProvider>
</ErrorBoundary>
</Provider>
</React.StrictMode>,
Expand Down
42 changes: 42 additions & 0 deletions front/src/app/pages/search/SearchResultPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import Button from "@codegouvfr/react-dsfr/Button";
import ButtonsGroup from "@codegouvfr/react-dsfr/ButtonsGroup";
import React, { ElementRef, useEffect, useRef, useState } from "react";
import { Loader, MainWrapper } from "react-design-system";
import { Helmet } from "react-helmet-async";
import { useDispatch } from "react-redux";
import {
AppellationDto,
ContactMethod,
SearchResultDto,
getMapsLink,
makeAppellationInformationUrl,
makeNafClassInformationUrl,
Expand All @@ -18,6 +20,7 @@ import { ContactByPhone } from "src/app/components/immersion-offer/ContactByPhon
import { ContactInPerson } from "src/app/components/immersion-offer/ContactInPerson";
import { HeaderFooterLayout } from "src/app/components/layout/HeaderFooterLayout";
import { SearchResultLabels } from "src/app/components/search/SearchResultLabels";
import { defaultPageMetaContents } from "src/app/contents/meta/metaContents";
import { useAppSelector } from "src/app/hooks/reduxHooks";
import { routes, useRoute } from "src/app/routes/routes";
import { searchSelectors } from "src/core-logic/domain/search/search.selectors";
Expand Down Expand Up @@ -50,13 +53,42 @@ const SearchResultSection = ({
</div>
);

const getMetaForSearchResult = (
currentSearchResult: SearchResultDto | null,
): {
title: string;
description: string;
} => {
if (!currentSearchResult) return { title: "", description: "" };
const hasAppellations = currentSearchResult.appellations?.length;
return {
title: `${currentSearchResult.name}${
hasAppellations
? ` - ${currentSearchResult.appellations
.map((appellation) => `${appellation.appellationLabel}`)
.join(", ")}`
: ""
}`,
description: `Fiche présentant l'immersion proposée par l'entreprise ${
currentSearchResult?.name
}${
hasAppellations
? `en tant que ${currentSearchResult.appellations.map(
(appellation) => appellation.appellationLabel,
)}`
: ""
}`,
};
};

export const SearchResultPage = () => {
const route = useRoute() as Route<
typeof routes.searchResult | typeof routes.searchResultExternal
>;
const currentSearchResult = useAppSelector(
searchSelectors.currentSearchResult,
);
const defaultMetaContents = defaultPageMetaContents.searchResult;
const feedback = useAppSelector(searchSelectors.feedback);
const isLoading = useAppSelector(searchSelectors.isLoading);
const formContactRef = useRef<ElementRef<"div">>(null);
Expand Down Expand Up @@ -99,6 +131,16 @@ export const SearchResultPage = () => {

return (
<HeaderFooterLayout>
<Helmet>
<title>
{getMetaForSearchResult(currentSearchResult).title} :{" "}
{defaultMetaContents?.title}
</title>
<meta
name="description"
content={getMetaForSearchResult(currentSearchResult).description}
/>
</Helmet>
<MainWrapper layout="boxed">
<>
{isLoading && <Loader />}
Expand Down

0 comments on commit 0b3fd1e

Please sign in to comment.