Skip to content

Support pre-rendering (SSG) for dynamic routes #1622

Description

@thescientist13

Motivation

Now that Greenwood has support for dynamic routing, it should be possible to build out the capability to generating static pages at build time using this convention

// src/pages/blog/[slug].js

export async function getStaticPaths() {
  return [{
    params: { slug: 'my-first-post' },
  }, {
    params: { slug: 'my-second-post' },
  }]
}

export default class BlogPostPage extends HTMLElement {
  #slug: string;

  constructor({ params }) {
    super();
    this.#slug = params?.slug;
  }

  connectedCallback() {
    this.innerHTML = `
      <body>
        <h1>${this.#slug}</h1>
      </body>
    `;
  }
}

Would generate two pages

public/
  blog/
    my-first-post.html
    my-second-post.html

Technical Design

We would also want to support something like getStaticProps too, to support the ability to configure props and paths in one-shot, e.g.

// src/pages/artists/[name].ts
import { getArtists, getArtistById } from '#services/artists.ts';
import type { Artist } from '#services/artists.ts';

interface StaticPaths {
  params: {
    name: string;
    id: number;
  }
}

interface PageProps {
  params: {
    artist: Artist;
  }
}

export async function getStaticPaths(): Promise<StaticPaths[]> {
  const artists = await getArtists();

  return artists.map(artist => {
    return {
      params: {
        name: artist.name,
        id: artist.id,
      }
    }
  });
}

export async function getStaticProps({ params }: StaticPaths): Promise<Artist> {
  const artist = await getArtistById(params.id);

  return artist;
}


export default class ArtistDetailsPage extends HTMLElement {
  #artist: Artist;

  constructor({ params }: PageProps) {
    super();
    this.#artist = params?.artist;
  }

  async connectedCallback() {
    this.innerHTML = `
      <body>
        <h1>${this.#artist.name}</h1>
      </body>
    `;
  }
}

Very much inspired by these implementations

Would also be good to include some types for this

Additional Context

It would be interesting to see if we still want to support the source plugin after this, or if we should deprecate it?
https://greenwoodjs.dev/docs/reference/plugins-api/#source

Metadata

Metadata

Labels

CLISSRTypes(cript)Requires type definition or TypeScript related work / documentationalpha.7documentationGreenwood specific docsfeatureNew feature or requestquestionFurther information is requestedv0.34.0
No fields configured for Feature.

Projects

Status
✅ Done

Relationships

None yet

Development

No branches or pull requests

Issue actions