
Security News
Risky Biz Podcast: Making Reachability Analysis Work in Real-World Codebases
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
prerender-spa-ultra
Advanced tools
Converts your JavaScript
-powered
SPA
web application into individual *.html
documents (one for each unique URL
your app has) filled with the content that your JavaScript
generated for
them.
Usage — Goals — Limitations & Caveats
(available as github action
, cli
command & npm
package)
When your app uses /deep/link/to/a/page
and you want to get a nice preview
of that page when its URL
is shared.
Link sharing over most channels like messaging apps, social networks or other
websites will not run JavaScript
, so they will preview your URL
based on
your static *.html
(which is likely empty). So if you want to preview
meaningful things that are shown with JavaScript
like the page main image,
or the correct page title you want to prerender
.
When you expect slow connection to your
SPA
or huge size of your JavaScript
. Instead of making your users wait staring
at a blank page you can prerender
that page, so that the html that gets
loaded includes the corresponding content and only make the users wait for
JavaScript
in order to interact with it
As a github action
(» see all GitHub action settings):
uses: antitoxic/prerender-spa-ultra@v1
with:
website_root: 'path/to/your/spa/dist'
As CLI
(» see all cli arguments):
# will automatically start http server
npx prerender-spa-ultra <path/to/your/output/dir>
You can prevent the http server from running or customize further via cli args.
As a npm
package (» see full config):
In contrast to the other approaches, when using
prerender-spa-ultra
programmatically you are responsible for starting the http server for your static files. » See examples how you can do this.
import { preRenderSite } from 'prerender-spa-ultra';
//...
await preRenderSite({
outputDir: 'path/to/output',
// This is the url at which you started the static http server
startingUrl: 'http://localhost:8000',
});
github action
usageBelow you can find an example of a job definition for prerendering your
repository via a GitHub workflow. Keep in mind that you can skip/remove
actions/setup-node@v3
, if you don't utilize npm
caching.
Whenever a GitHub workflow runs, nodejs
is already available and is the exact
version needed, since prerender-spa-ultra
is written considering this.
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
cache: npm
- name: Install
run: |
npm install
- name: Build
run: |
npm run build
- name: Prereder the freshly built app
uses: @antitoxic/prerender-spa-ultra@v1
id: prerender
with:
website_root: 'path/to/your/app/dist'
# the options below are optional:
max_concurrent_pages: 10
meta_prerender_only: "1"
selector_to_wait_for: "[data-scraper=ready]"
If you are looking to deploy the final prerendered files to Cloudflare you can add the following action in the end of your job:
- name: Deploy to cloudflare
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run:
npx wrangler pages publish path/to/your/app/dist --project-name
REPLACE_WITH_YOUR_PROJECT_NAME
CLI
usageCheck the help output of npx prerender-spa-ultra
or the self-explanatory
source code of the cli:
https://github.com/antitoxic/prerender-spa-ultra/blob/main/src/prerenderer/cli.ts#L9-L83
npm
package usagepreRenderSite(...)
config type definitions:
https://github.com/antitoxic/prerender-spa-ultra/blob/main/src/prerenderer/prerender.ts#L59-L71
If you are not using the peer dependency serve-handler
to
run http server for your static files you can skip
You can enable logging:
PRERENDER_SPA_ULTRA_DEBUG=1 npx prerender-spa-ultra ....
# or
PRERENDER_SPA_ULTRA_DEBUG=1 <your command that uses this package programatically>
or as GitHub job step:
- name: Pre-render
uses: antitoxic/prerender-spa-ultra@v1
env:
PRERENDER_SPA_ULTRA_DEBUG: 1
with:
website_root: dist
The prerender-spa-ultra
's cli & GitHub action internally use the
serve-handler
npm package to start a http server but there are multiple
alternatives:
cd <path/to/static/files/root/dir/>
# and then one of:
npx serve --single
npx node-static --spa
npx http-server --proxy "http://localhost:8080?"
If you are trying to minimize dependencies and don't want to use those, you can
rely on the included http-server.py
(python 3):
cd <path/to/static/files/root/dir/>
python <path/to/node_modules>/prerender-spa-ultra/src/http-server.py
example.com/#route
). This is because the server never sees the #...
part of the url, so it can't find a file based on it. If you are in this
scenario you can try migrating to html5 push history.*.js
, *.css
) should not be linked as
relative paths since pre-rendering creates a nested folder structure to
match the urls you have. Instead, those should be linked from your URL
root (/...
).pathname
to be one and the same url. You can override this by providing a
custom cleanUrl
and getFilename
functions to preRenderSite
. It will be
up to you to configure your http server to route such urls with query params
to their respective static file (created by getFilename
).cleanUrl
trims any slashes, which means some/url/path/
and
some/url/path
will be considered the sameprerender-spa-ultra
puppeteer-core
), nothing else besides the
peer dependency for the automatic http server in CLI (which you can opt
out). This also means saving build-time otherwise spend downloading
packages & binaries on every buildprerender-spa-ultra
is
to be easy to understand from just reading the code.prerender-spa-ultra
prerender-spa-ultra
has a narrow goal. Let's keep expectation clear:
prerender-spa-ultra
is not going to optimize the output html files. It's
far more efficient to do that beforehand in your main SPA assets-build step.prerender-spa-ultra
is not going to prerender any site you provide. This
is specifically made to work together with the local http static file server
included in it. The purpose of this is making sure you get the maximum
performance + taking care of some edge case scenarios in headless chromeprerender-spa-ultra
is not going to provide 100% of the options as CLI
arguments. Only the basic customizations are possible by passing CLI
arguments. If you want to do something more advanced, import
prerender-spa-ultra
as a nodejs module and call it with all the options you
need.prerender-spa-ultra
is not going to install chrome or chromium. If you
are using GitHub workflows or similar, it's likely to have it already
installed. Otherwise, you can use the OS package manager to install or use
node-chromium
(npm install chromium
)Will be opened very soon, waiting for GitHub sponsorship approval :)
JSDOM
since it can't safely execute <script/>
shttps://developers.cloudflare.com/workers/wrangler/ci-cd/
To use cloudflare cli (wrangler
) from CI like GitHub actions you need to
create CLOUDFLARE_API_TOKEN
and add it as a secret in that CI environment
Maybe you will need to set CLOUDFLARE_ACCOUNT_ID
if you have more than 1
account associated with this API token.
Must expose GitHub secret as ENV variable (not done by default)
FAQs
Crawls & Pre-renders a site
We found that prerender-spa-ultra demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
Security News
/Research
Malicious Nx npm versions stole secrets and wallet info using AI CLI tools; Socket’s AI scanner detected the supply chain attack and flagged the malware.
Security News
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.