Jamstack sites are based on pre-rendering and decoupling principles, using JavaScript, APIs, and Markup. Sites that use static generation are fast since the content is generated in advance rather than waiting for the end user to request it.
Pre-rendering
Pre-rendering is the method of generating static HTML rather than serving it through client-side JavaScript. Our sites can be built faster without having to be served on the fly.
Pre-rendering can be done using Server Side Rendering (SSR) or Static Site Generation (SSG). Static Site Generation is the most common pre-rendering method used in Jamstack, which means that the HTML is generated during the build process.
Decoupling
Decoupling means that the pages that make up your site must be independent of any external server. As with WordPress, where a server must be running and PHP must be serving your site, Jamstack's documents are created in advance.
Jamstack in ThemeForest
Your item must align with this definition and include pre-rendering in order to be included in the Jamstack category. Due to the lack of pre-rendering in JavaScript libraries/frameworks such as React, Vue, and Angular, these items belong in the Site Templates category rather than the Jamstack category.
It is true that some Jamstack definitions do not require your site to use JS or APIs to be considered Jamstack, but our stance is that items without support for Static Site Generation go into Site Templates, and SSG-compatible items go into our Jamstack category.
Some of the most popular frameworks used to make Jamstack sites are: Next.js, Nuxt.js, SvelteKit, Gatsby.js, Eleventy (11ty)
Examples of Allowed Jamstack items:
- Next.js + Headless WordPress
- SvelteKit + Strapi
- Nuxt.js + DatoCMS
- Gatsby.js + Google Spreadsheets
- Eleventy + .md files — https://www.11ty.dev/docs
Jamstack Example Site with Next.js
As a pre-rendering technique, Next.js recommends Static Site Generation.
Consider the case where you want to build a Bookshelves App and make use of Gutenberg.org's API. Since this information rarely changes, the books data for this site is needed ahead of time.
Let's generate a new Next.js site with npx create-next-app jamstack --ts
and clean up some of the markup that we won’t use:
Next.js has a function called getStaticProps; with getStaticProps "Next.js will pre-render this page at build time using the props returned by it."
Once you run yarn build
, the data will be pre-fetched and placed in the .next directory as .json files.
Let’s explain what’s going on in getStaticProps
:
- We first fetch our resource and grab the returned JSON.
- The payload returned has 4 properties: count, next, previous and results. Since we’re only interested in the results that’s what we return in the props (
books.results
).
Building the Main Page UI
This is pretty standard JSX so you should be able to understand clearly what’s going on here. The only thing that stands out is the Link component:
<Link href={`book/${book.id}`}>
<a>{book.title}</a>
</Link>
Currently, we have only a list of all books that is derived statically, but we also need individual pages to display information about each book. The link above will throw a 404 error since we haven't yet generated the single pages for each book. We'll take care of that next.
Building single pages for each book
Next.js employs a file-system routing system, so we will create a book
directory under the pages
directory and then create a [id].tsx
page, which is how Next.js does dynamic routing.
In this page we need to use two functions, getStaticProps
(which we covered above) and getStaticPaths
. From the docs “When you export a function called getStaticPaths
from a page that uses dynamic routes, Next.js will statically pre-render all the paths specified by it.”
The idea is simple: When we use getStaticPaths
, Next.js will produce a new HTML page for each book/:id
, so if we have a resource with a thousand books with ids ranging from 1 to 1000, we will get a thousand HTML pages 1.html
, 100.html
and so on. Ok so, with that out the way let’s continue.
In your [id].tsx
page put some JSX to render some elements.
Building our Static Paths
It’s pretty clear what’s happening here:
- We fetch a list of all our resources and grab the JSON payload from the response.
- Then we map through the results and return an array of objects for each book. The final result should look like this:
[
{ params: { id: '1' } },
{ params: { id: '2' } },
{ params: { id: '3' } }
]
Finally we return our paths
array and set fallback
to false
. You can learn more about the fallback
property here: https://nextjs.org/docs/api-reference/data-fetching/get-static-paths#fallback-false
If we run yarn build
Next.js will throw an error because getStaticProps
is required when using getStaticPaths
so let’s fetch our data for each book:
The params
object is the one returned from getStaticPaths
, so all you have to do is dereference the params object by taking the id
property.
💡 In Gutendex API you can pass book IDs with the query string ids
like so ?ids=10,22
so we use it to build our single pages.
Again, we take the JSON payload from the response and return our single book object in the props, now we’re ready to build our UI.
Single Book Page UI
If you run yarn build
right now and go to the dist directory .next
you will find all your single pages and its data:
Pretty simple right?
You can find the code here: https://github.com/ivorpad/books-next-ssg