react-dsfr
GitHubComponentsPlayground
  • 🔧Initial setup
  • 🔀Integration with routing libs
  • 🦺Class names type safety
  • 🎨Colors
  • 🧩Components
  • ☑️Icons
  • 💅CSS in JS
  • 🌎Internationalization
  • 🌅Importing assets
  • 🤝MUI integration
  • 🕊️Custom Branding
  • 📖Storybook
  • 📊Analytics
  • 🔒Content-Security-Policy
  • 📦Publishing a NPM modules that depends on react-dsfr
  • 💟Contributing
Powered by GitBook
LogoLogo

Links

  • GitHub
  • Playground
  • Components

2022-2023 Pôle logiciel libre d'Etalab - MIT license

On this page

Was this helpful?

Edit on GitHub
Export as PDF

Integration with routing libs

Like react-router or Next.js file system based route.

PreviousInitial setupNextClass names type safety

Last updated 1 year ago

Was this helpful?

Depending on the framework or routing library you are using, links between pages are not handled the same way.

Usually, you'll have a <Link /> component provided by your routing library of choice. You need to let react-dsfr know about it so that whenever a link is needed in a DSFR component, you can provide the correct props for your <Link /> component.

When registering your Link component, its props type will propagate to the react-dsfr API.

This is how you are instructed to set it up by default (no change from the guide)

app/StartDsfr.tsx
"use client";

import { startReactDsfr } from "@codegouvfr/react-dsfr/next-appdir";
import { defaultColorScheme } from "./defaultColorScheme";
import Link from "next/link";

declare module "@codegouvfr/react-dsfr/next-appdir" {
    interface RegisterLink { 
        Link: typeof Link;
    }
}

startReactDsfr({ 
	defaultColorScheme, 
	Link
});

export default function StartDsfr(){
        //Yes, leave null here.
	return null;
}

Examples

Client side routing

import { Card } from "@codegouvfr/react-dsfr/Card";

<Card
  linkProps={{
    to: "/my-page"
  }}
/>

The <Link /> component from react-router will be used.

External links:


linkProps={{
  href: "https://example.com"
  target="_blank"
}}

When react-dsfr detects that the href points to an external website it will use a regular <a/> instead of the <Link /> component.

Mailto links


linkProps={{
  href: "mailto:contact@code.gouv.fr"
}}

Same goes for the mailto links.

Converting a link to a button

linkProps={{  
  href: "#"
  onClick: ()=> { /* ... */ }
}}

React-dsfr will automatically convert the underlying HTML element into a <button /> that looks like a link for better Accessibility.

pages/_app.tsx
import type { AppProps } from "next/app";
import { fr } from "@codegouvfr/react-dsfr";
import { createNextDsfrIntegrationApi } from "@codegouvfr/react-dsfr/next-pagesdir";
import Link from "next/link";

// Only in TypeScript projects
declare module "@codegouvfr/react-dsfr/next-pagesdir" {
    interface RegisterLink { 
        Link: typeof Link;
    }
}

const { 
    withDsfr,
    dsfrDocumentApi
} = createNextDsfrIntegrationApi({
    defaultColorScheme: "system",
    Link
});

export { dsfrDocumentApi };

function App({ Component, pageProps }: AppProps) {
    return <Component {...pageProps} />;
}

export default withDsfr(App);

Examples

Client side routing

import { Card } from "@codegouvfr/react-dsfr/Card";

<Card
  linkProps={{
    href: "/my-page"
  }}
/>

The <Link /> component from react-router will be used.

External links:


linkProps={{
  href: "https://example.com"
  target="_blank"
}}

When react-dsfr detects that the href points to an external website it will use a regular <a/> instead of the <Link /> component.

Mailto links


linkProps={{
  to: "mailto:contact@code.gouv.fr"
}}

Same goes for the mailto links.

Converting a link to a button

linkProps={{  
  to: "#"
  onClick: ()=> { /* ... */ }
}}

React-dsfr will automatically convert the underlying HTML element into a <button /> that looks like a link for better Accessibility.

import React from "react";
import ReactDOM from "react-dom/client";
import { startReactDsfr } from "@codegouvfr/react-dsfr/spa";
import { Link, type LinkProps } from "@tanstack/react-router";

startReactDsfr({ 
    defaultColorScheme: "system", 
    Link 
});

declare module '@codegouvfr/react-dsfr/spa' {
  interface RegisterLink {
    Link: (props: LinkProps) => JSX.Element
  }
}

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
    <React.StrictMode>
            {/* ... */}
    </React.StrictMode>
);

After that you will have type safety on the linkProps, you can use the to property as you would on the react router's <Link /> component! Note that if you want to link to external website (or use mailto:) you can use the href property instead of the to property (see below).

If you have a link that is a mailto: or a link to an external page, use the href property instead of to. Example:

<Header
    navigation={[
        {
            text: "Contact",
            linkProps: {
                href: "mailto:support@data.gouv.fr"
            }
        },
        {
            text: "Écrire au président"
            linkProps: {
                href: "https://www.elysee.fr/ecrire-au-president-de-la-republique/"
            }
        }
    ]}
/>

In consequence there isn't anything to setup.

Examples

Client side routing

import { Card } from "@codegouvfr/react-dsfr/Card";
import { routes } from "...";

<Card
  linkProps={routes.myPage().link}
/>
import React from "react";
import ReactDOM from "react-dom/client";
import { startReactDsfr } from "@codegouvfr/react-dsfr/spa";
import { Link } from "react-router-dom";
startReactDsfr({ 
    defaultColorScheme: "system", 
    Link 
});

//Only in TypeScript projects
declare module "@codegouvfr/react-dsfr/spa" {
    interface RegisterLink { 
        Link: typeof Link;
    }
}

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
    <React.StrictMode>
            {/* ... */}
    </React.StrictMode>
);

Examples

Client side routing

import { Card } from "@codegouvfr/react-dsfr/Card";

<Card
  linkProps={{
    to: "/my-page"
  }}
/>

The <Link /> component from react-router will be used.

External links:


linkProps={{
  to: "https://example.com"
  target="_blank"
}}

When react-dsfr detects that the to points to an external website it will use a regular <a/> Instead of the <Link /> component.

Mailto links

linkProps={{
  to: "mailto:contact@code.gouv.fr"
}}

Same goes for the mailto links.

Converting a link to a button

linkProps={{  
  to: "#"
  onClick: ()=> { /* ... */ }
}}

React-dsfr will automatically convert the underlying HTML element into a <button /> that looks like a link for better Accessibility.

You should be able to infer what needs to be done refering to the react-router instructions.

If the library you are using doesn't export a <Link /> (like type-route for example) component, there isn't anything to do.

This is how you are instructed to set it up by default (no change from the guide)

Example .

Due to the fact that is also implementing module augmentation it's just a tiny bit less straight forward to set up but it works great!

unlike most routing library doesn't export a <Link /> component, <a /> are used directly.

Example .

If you are starting a new project you might want to use in place of as it is, at least in my opignion a much better routing library.

Everywhere a DSFR component accepts a xxxLinkProps you are expected to provide an object with a to property because react-router's<Link /> component expects a to prop instead of the typical href. You can find an example .

🔀
here
@tanstack/react-router
type-route
here
here
react-router
TanStack Router
Initial setup
Initial setup