Come funziona il Dynamic Routing in NextJs

Quando si parla di Dynamic Routing in NextJs, si intende la generazione dinamica di più percorsi. Come sappiamo un percorso creato tramite la cartella app, è definito da un directory, il contenuto del percorso è definito dal file page.js (clicca qui per saperne di più). Questo concetto rimane valido pure con il dynamic routing, un percorso dinamico è definito dal fatto che la cartella si chiami [slug]. Facciamo subito un esempio per capire meglio:

Ho organizzato tutta la struttura del progetto all’interno del file src, si tenga presente che tutti i percorsi sono basati sulla cartella appena citata. Quindi se si utilizza la cartella app senza la cartella src, i percorsi utilizzati nell’esempio dovranno essere adattati.

Il percorso dinamico lo si trova al seguente percorso: src/app/items/[slug], il file page.js al suo interno ci permetterà di creare il percorso dinamico, ma iniziamo facendo un passo alla volta. Il sito basilare che andremo a creare ci permetterà di visualizzare nella home page una serie di prodotti, in questo caso i prodotti saranno: matita e penna. Quindi in questo caso i percorsi dinamici saranno: src/app/items/matita e src/app/items/penna, ma si può pensare di creare pure percorsi dinamici per: gomme, fogli, cartelle e altro… 

I dati che visualizzeremo li ho salvati in questo percorso: src/items, ogni file è un file .md quindi un file markdown, per permettere a NextJs di leggerli installiamo subito una libreria JavaScript:

npm install gray-matter

Specifichiamo l’ultima cosa di questo progetto, si può notare un file itemsMenager.js, questo è un file che creeremo che ci permetterà di gestire l’interfaccia tra Gray-Matter e NextJs.

1) Link dinamici

Iniziamo a creare dei link dinamici all’interno del seguente percorso: src/app/page.js

//in page.js
import {getMetaData} from '../lib/itemsMenager.js';
import Link from 'next/link'

export default async function Page() {

  const items= getMetaData();
  console.log(items)
  return ( 
    
{items.map((item) => (

{item.nome}

))}
) }

Tramite la funzione getMetaData importata da itemsMenager (che dopo creeremo), estraiamo tutti gli oggetti di cui dobbiamo creare un percorso (in questo caso la matita e la penna) e poi tramite un ciclo andiamo a creare per ognuno di loro un percorso dinamico.

//in itemsMenager.js 
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';

//otteniamo la directory di src/items
const itemsDirectory = path.join(process.cwd(), 'src/items');

export function getMetaData() {
  // tutti i nomi dei file nella cartella selezionata
  const dirs = fs.readdirSync(itemsDirectory )

  const metaFiles = dirs.map((dirFile) => {
    const url = path.join(itemsDirectory , dirFile);

    //la variabile contiene il percorso del file che ci interessa
    const file = fs.readFileSync(url,'utf8')
    //ora estraiamo tutti gli elementi contenuti all'interno del file
    const markFile= matter(file).data;
    const nome= markFile.nome;
    return {
      url:  'items/'+dirFile.replace('.md', ''),
      nome,
    };

  })
  return metaFiles
}

In questa parte abbiamo già scritto un bel pò di codice e importato qualche libreria: fs ci permetterà di interagire con i file, path ci aiuterà a gestire i percorsi mentre gray matter ci aiuterà a leggere i file md. 

Alla funzione abbiamo fatto restituire solo il nome dell’oggetto, una singola variabile che abbiamo ottenuto dal file markdown. In modo analogo possiamo accedere ad ogni sua variabile tramite: markFile.costo, markFile.descrizione e così via… 

Inoltre per restituire ogni singolo valore contenuto nel file possiamo fare:

return {
  url:  'items/'+dirFile.replace('.md', ''),
  … markFile,
};  

2) Percorsi dinamici

Passiamo ora a creare i percorsi dinamici:

//in src/app/intems/[slug]/page.js

import {getItemIds, getItemById} from '/src/lib/itemsMenager.js'

export default async function Page({params}) {
  const itemData = await getItemById({id: params.slug})
  return (

    

{itemData.nome}

{itemData.costo}

Disponibile: {itemData.quant}

{itemData.descrizione}

) }
export async function generateStaticParams() { return getItemIds(); }

Tralasciando le due funzioni importate, che andremo a definire tra un attimo, concentriamoci ora sul come creare un percorso dinamico. 

Tramite generateStaticParams() possiamo creare dei parametri statici, getItemIds restituisce un array composto dal nome di tutti i file presenti nella seguente cartella: src/items, senza estensione. 

Ora passando getItemIds alla funzione principale tramite {params} e tramite params.slug possiamo ottenere il percorso selezionato dall'utente, se per esempio ha navigato su ‘src/app/items/penna’ tramite params.slug otteremmo ‘penna’. 

Tramite la funzione getItemById passandogli ‘id’ che è nel caso analizzato prima ‘penna’ otterremo i singoli dati della biro. 

Andiamo a vedere come sono definite le due funzioni: 

// aggiungi il codice in itemsMenager.js
export function getItemIds(){
  const fileNames = fs.readdirSync(itemsDirectory );
  return fileNames.map((fileName) => {

      slug: fileName.replace('.md', '')


  });
}

export async function getItemById({id}){
  const url = path.join(itemsDirectory , `${id}.md`);
  const file = fs.readFileSync(url,'utf8')

  const matterResult = matter(file);

  return {
    ...matterResult.data,
  };
}

Con questo abbiamo visto come funzionano i percorsi dinamici, inoltre abbiamo tratto anche velocemente gray matter, se vi è piaciuto vi consiglio di approfondire.