Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gatsby / Static Website Generator support ? #204

Open
wiwski opened this issue Oct 27, 2023 · 11 comments
Open

Gatsby / Static Website Generator support ? #204

wiwski opened this issue Oct 27, 2023 · 11 comments

Comments

@wiwski
Copy link

wiwski commented Oct 27, 2023

Est-ce qu'il est possible d'utiliser la librairie avec Gatsby - en vue de générer un Static Website ?
En mode développement ça fonctionne très bien, mais une erreur survient lors du build.

L'erreur est dans le module start.js sur cette ligne :

assert(isBrowser);

J'appelle startReactDsfr dans le code de ma page Index :

...
import { startReactDsfr } from "@codegouvfr/react-dsfr/spa";
...
startReactDsfr({ defaultColorScheme: "system" });
...

const IndexPage: React.FC<PageProps<DataProps>> = ({ data, path }) => {
    ...
}

@wiwski
Copy link
Author

wiwski commented Oct 27, 2023

En suivant les instructions pour Next.js App Router, le build a fonctionné ! Je vous laisse fermé l'issue ou la laisser ouverte pour ajouter de la documentation sur ce framework ?

@garronej
Copy link
Collaborator

Salut @wiwski,

Je n'ai pas fait d'intégration spécifique pour gatsby mais je pense que tu peut t'en tirer simplement en garentissant que le startReactDsfr() ne soit appeler que sur le navigateur.

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

if (typeof window !== "undefined") {
  // Seulement sur le client
  startReactDsfr({ defaultColorScheme: "system" });
}

Sa ne sera pas tout a fait aussi clean qu'avec l'integration Next, c'est à dire que si l'utilisateur a son navigateur en dark mode, il va voir quellques milliseconde l'app en blanc puis ça va passer en dark mode.

Si tu veux on peut fournir une intégration spécifique import { startReactDsfr } from "@codegouvfr/react-dsfr/gatsby. C'est pas un problème, je ne savais juste pas que Gatsby etais utiliser dans l'état.

Si tu me fait un repo minimal avec React-DSFR pre set up je peut regarder.

@wiwski
Copy link
Author

wiwski commented Oct 27, 2023

@garronej
Merci pour ta réponse ! Il semble que mettre <StartDsfr /> dans la balise <Head> comme indiqué dans la doc pour Next.js App Router fait l'affaire.
Je vous ferai un retour si jamais je vois un pb spécifique à Gatsby mais je ne vois pas quoi pour l'instant, à part peut-être la navigation (qui n'utilise pas le Link de next. A voir...) 🙂

@garronej
Copy link
Collaborator

Ok super. Ca me surrprend beaucoup mais c'est cool si ça marche.
Il faut quand même que tu puisse dire a react-dsfr quelle lib de routing tu utilise si non tu va avoir des full reload a chaque chaque clique sur un link.
Je suis preneur pour un retour d'expérience, et de pouvoir envoyer un link vers ton repo pour les autres qui utiliserais Gatsby.

@wiwski
Copy link
Author

wiwski commented Oct 30, 2023

@garronej du nouveau :
Pour éviter les full reload sur les Link, j'ai adapté le module startDsfr et ça semble fonctionner :

"use client";

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

const Link = ({ ...props }: RegisteredLinkProps) => {
  const { ref, href, ...newProps } = props;
  return <GatsbyLink to={href || "#"} {...newProps} />;
};

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

startReactDsfr({ defaultColorScheme, Link });

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

Il y a probablement des choses à adapter pour avoir une totale conversion des liens Next vers Gatsby. D'ailleurs si tu as des idées je suis preneur.

Je continuerai à poster si je vois des améliorations. Et je posterai le lien du repo quand il sera sur github (probablement cette semaine).

@garronej
Copy link
Collaborator

garronej commented Oct 30, 2023

Salut @wiwski,

je pense que le mieux serais de faire un adapter pour Gatsby.

Par contre attend, je crois que tu n'a pas bien compris ce que react-dsfr permet par rapport au rooting.

https://react-dsfr.codegouv.studio/routing

En fait tu peut déclarer le Link component que tu utilise, react-dsfr va l'utiliser en interne et a chaque fois que tu va avoir un truck linkProps tu va retrouver le type de props pour ton composant link.
Ici GatsbyLink.

Ce que tu veux faire c'est:

import React from "react";
import ReactDOM from "react-dom/client";
import { startReactDsfr } from "@codegouvfr/react-dsfr/next-appdir";
import { Link } from "gatsby";  

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

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

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

...Tout simplement.
Après tu vera sur tes bouttons et tout tu va pouvoir passer les même props que ton link gatsby accepte.

Je suis très dessu parce que le fait que react-dsfr puisse fonctionner avec nimporte quelle librairie de routing client est une des choses dont je suis le plus fier sur cette lib mais maleureusement tout le monde est mistifier par l'augmentation du type global. 😢

@wiwski
Copy link
Author

wiwski commented Oct 31, 2023

@garronej
Hello @garronej, c'est ce que j'ai essayé au début mais la prop Link de startReactDsfr n'est pas compatible avec le Link de Gatsby, d'où le petit bout de code pour effectuer la conversion. Ca a l'air de très bien marcher.

Bravo pour les différentes reflexions autour de react-dsfr, c'est bien pensé 👍

@garronej
Copy link
Collaborator

garronej commented Oct 31, 2023

Merci!
Mais la prop link de startDsfr elle est contrainte par toi. C'est toi qui dit a react-dsfr ce qu'est ˋLinkˋ, pas l'inverse.
Il faudrais que je bootstrap un projet Gatsby mais il n'y a pas de raison qu'on ne pluissent pas utiliser le Link de gatsby juste comme on peut utiliser le Link de Next ou celui de React Routeur.

Tu as essayé précisément mon code?

@wiwski
Copy link
Author

wiwski commented Oct 31, 2023

Hmm.. Je comprends ton point en lisant la doc du routing pour react-router qui utilise la même prop to que le Link Gatsby.

Oui j'ai essayé en remplaçant import { startReactDsfr } from "@codegouvfr/react-dsfr/cra"; par import { startReactDsfr } from "@codegouvfr/react-dsfr/next-appdir"; car je n'ai pas de module cra dans mon package.

Alors j'ai une erreur sur la prop Link de startReactDsfr:

Type 'typeof Link' is not assignable to type '(props: Omit<HTMLAnchorProps, "children"> & { children: ReactNode; }) => ReactNode'.
  Type 'typeof Link' provides no match for the signature '(props: Omit<HTMLAnchorProps, "children"> & { children: ReactNode; }): ReactNode'.ts(2322)

@garronej
Copy link
Collaborator

En effet, @wiwski, c'était une erreur de ma part.
J'avais oublié l'existence des composants de classe. En fait, le <Link /> de Gatsby est un composant de classe, et mon type qui gère l'inférence n'arrivait pas à extraire les props du Link de Gatsby.
Je viens de corriger cela.
Pour aggraver les choses, dans le snippet que je t'ai partagé, j'ai importé /cra qui n'existe plus depuis longtemps. (J'ai supprimé toutes les références dans la documentation).
À ce jour, nous avons trois adaptateurs :

  • /spa : Pour toutes les applications monopages qui n'ont pas de SSR, donc les projets Vite et CRA.
  • /next-appdir : Pour Next en mode App Router.
  • /next-pagesdir : Pour les projets Next en mode legacy qui utilisent encore le routeur Pages.
    Il serait bon d'ajouter /gatsby. Je serais ravi si tu pouvais partager ton repo quand il sera ouvert. Je vais étudier ta configuration et créer un adaptateur sur mesure pour le framework. Pour le moment, je n'ai pas le temps de travailler avec Gatsby.

En attendant, voici le snippet que tu peux implémenter pour obtenir les types corrects au niveau du routage (après avoir mis à jour @codegouvfr/react-dsfr à la dernière version 0.78.5) :

"use client";

import React from "react";
import { startReactDsfr } from "@codegouvfr/react-dsfr/next-appdir";
import { Link } from "gatsby";

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

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

export function StartDsfr() {
    // Oui, laissez null ici.
    return null;
}

Now if you use a component that includes hyperlink you'll get the correct type.

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

const node = (
    <Card
        linkProps={{
            to: '#'
        }}
        title="Intitulé de la carte (sur lequel se trouve le lien)"
    />
);

@wiwski
Copy link
Author

wiwski commented Nov 27, 2023

Salut @garronej, j'ai mis à jour à la dernière version et utilisé ton snippet et ça fonctionne très bien, merci !

Pour info, c'est toujours en phase initial de développement, mais le repo est dispo ici : https://github.com/betagouv/euphrosyne-digilab

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants