This is a demo of a Next.js application hosted on Ubuntu Linux. It also includes a Postgres database and an Nginx proxy. View the code.
Random Pokemon: tentacruel
This value was retrieved with fetch
from an API. This page is served dynamically, fetching a random Pokemon on each request. Reload to see a new Pokemon.
Next.js supports image optimization out of the box with next start
. The image above is using the default image optimization on the Next.js server.
In Next.js 15, you no longer need to install sharp
manually for image optimization, whether local or remote. You can also use a custom image loader for external optimization services.
You can also bring your own custom image loader, if you would prefer to use a different service. You can view an example here, which you can enable through next.config.ts
.
The Next.js App router supports streaming responses. This demo usesSuspense
with an async
component to stream in different components with a delay. We let Nginx handle compression for our application, and then disable proxy buffering to enable streamed responses.
This route reads and writes to our Postgres database, which is in its own Docker container. It uses Drizzle for the ORM. There is also a cron job that resets the demo data every 10 minutes. You can manually hit the endpoint the cron uses by sending a POST
to /db/clear
By default, Next.js ISR uses an lru-cache
and stores cached entries in memory. This works without configuration, for both caching data as well as ISR, in both the Pages and App Router.
If you prefer to override the cache location, you can store entries in something like Redis. For multi-container applications, this is strongly recommended, but for this single container app it’s not necessary.
For this demo, we have a route that retrieves data with fetch
from an API, then adds a time-based revalidate
time of 10 seconds. This indicates it will be "fresh" for a maximum of that time. You can view the s-maxage=10, stale-while-revalidate=31536000
response header for the page.
The default stale-while-revalidate
time for static pages that do not specify a revalidate
time is 1 year, however, this can also be configured with swrDelta
in next.config.ts
.
The /protected
route is protected by a cookie. You will be redirected back to /
. To view the route, add the protected=1
cookie in the browser.
Middleware does not have access to all Node.js APIs. It is designed to run before all routes in your application. However, we are planning to allow support for using the entire Node.js runtime, which can be necessary when using some third-party libraries.
It is not recommended to do checks like fetching user information from your database inside of Middleware. Instead, these checks should happen before queries or mutations. Checking for an auth cookie in Middleware in the preferred pattern.
Next.js includes an instrumentation
file that runs some code when the server starts.
This instrumentation file will be stabilized in Next.js 15. A common use case is reading secrets from remote locations like Vault or 1Password. You can try this by setting the appropriate variables in your .env
file for Vault, though it's not required for the demo.
Next.js supports loading environment variables from .env
files.
When reading values from a Server Component, you can ensure that the env var is read dynamically every time. For container setups, a common use case here is to provide different env vars per environment, with the same Docker image.
This value was read from process.env
: maplesmoked