Astro design patterns examples, client-server state management, markdown, caching
showcase examples for isolated simple usage patterns
This is a minimal example that shows the node version running
shared global var demo. reload the page to increment the counter. All pages share the same counter
python test.py
output with the page being loaded from a browser and switching pages
Server listening on http://127.0.0.1:3000
Max memory consumption: 4.44 MB
Max memory consumption: 51.71 MB
Max memory consumption: 51.71 MB
Max memory consumption: 54.93 MB
SSE: Server Sent Events. global var using a timer and Emitter
Server keeps couter state. reloading the page has no effect on the counter
requires Node18 for ReadableStream(), currently only on Gitpod
A simple approach for multiple instances of a component. A <script>
is included once. It initiates all components of a class on page load without requiring unique identification
Decentralized scoping js execution on an Astro component used mutiple times on the same page
Constraints :
Alternatives:
sequence_uid
function gets multiple instances for some reason such as being budled separately.Optionally:
using environment variables from file in astro.config.mjs
and .js
server files
integration : @astrojs/node
adapter : node-standalone
todo test with loadEnv from ‘vite’
Page not found redirect to 404
[...path].astro
custom 404 page from : https://codepen.io/Stephane/pen/Jdozrp
setTimeout
This is about dynamically importing a js script only when the component logic decides to do it. In this case, after 2 seconds from window load.
Not only <Card title="Test" client:visible/>
is not supported by astro as directive reserved for framework components only, but also, it does not give fine granularity to decide exactly when to load a js script.
Note: Testing this example only makes sense in production mode (with build and run). Only gitpod left because it has a shell script that builds and runs by default while the others (StackBliz and Codesandbox) run in preview mode.
This example uses the experimental prerender
feature. index page '/'
is prerendered while '/rerender'
page is server side rendered on every fetch
export const prerender=true
Testing environment variables in deno and deno.deploy
live demo : https://astro-env.deno.dev/
project : https://dash.deno.com/projects/astro-env
await Promise.all()
and item.render()[...slug].astro
with getEntryBySlug()This counter uses a cookie counter=1
to persist through pages relaod despite being a client counter.
For Astro SSR there is a simplicity advantage for using a cookie over using client sotrage :
Note : Only a single counter is used in this example given that a single cookie is used
Note : For a demo using cookies, the Astro.cookies could only be read in Gitpod
todo : check example with blocking head script can solve ssg
sessionStorage
for client side persistency, and therefore avoids cookies.put
request to a server endpointsession_id
parameter, it is passed to the client within the html components, the client takes it upon page load and use it in case no sessionStorage session_id available. Then stick it to the URL parameters for future queriesNote : this implementation is for demo purpose only and suffers from memory leak as old session_id’s are not deleted.
Counts the pages load for a specific client with cookies. This examples shows how to get and set a cookie from a .astro page while example 13 gets the cookie from the server and set it from the client.
example to show how to generate an html string out of a component using a Wrapper and Astro.slots.render()
Generate javascript that can be executed on the client. The UID set by the server, is fetched by the client inside a javascript file
Note : although functional, this method is not recommended due to Vite complaning about dynamic import and security risk it implies.
example using astrojs/image integration
example using astrojs/image integration
adapter : node-standalone
proxy : express
cache event-drive content
call purge method
put pass througn
Running mode :
pnpm run preview
listens on port 4000pnpm run proxy
listens on port 3000hashes.json
but could be with a db or API)hashes.json
)Same concept as the previous example but here the cache proxy and Astro SSR are combined in the same express App with Astro running in middleware mode
Example for testing SVG usage within .astro
, .md
and .mdx
This highlights incompatibility of inlined SVG when injected from remark/rehype plugins in an mdx file
xmlns:xlink
gets treated as .jsx and converted to xmlnsXlink
, xmlns
or xmlnsxlink
, all of which break the SVG renderingNote :
features
astro-remote
works with astr v2 but not an official integrationHeading, CodeBlock, CodeSpan, Note
no mapping of custom components, e.g. images,…4 Locations where to alter server config
/vite.config.js
/astro.config.mjs:server.port,proxy
/astro.config.mjs:site.server.port,proxy
/src/libs/inetgration-test.js:config_setup().update_config()
summary
Benchmark results charts : https://microwebstacks.github.io/astro-examples/
./26_serverless-counter-netlify
shared global var demo. reload the page to increment the counter. All pages share the same counter
Note ! in serverless deployment, the in-memory state only persistes temporarily until a different instance is started
./27_serverless-counter-cloudflare
shared global var demo. reload the page to increment the counter. All pages share the same counter
Note ! in serverless deployment, the in-memory state only persistes temporarily until a different instance is started
./28_serverless-counter-vercel
shared global var demo. reload the page to increment the counter. All pages share the same counter
Note ! in serverless deployment, the in-memory state only persistes temporarily until a different instance is started
./29_serverless-counter-denodeploy
shared global var demo. reload the page to increment the counter. All pages share the same counter
Note ! in serverless deployment, the in-memory state only persistes temporarily until a different instance is started
.env not taken has to manually inject env var DENO_DEPLOY_TOKEN
./30_serverless-counter-deno-redis
Deno.version
not working resulting in crash on deploydemo for variable persisted on redis database. reload the page to increment the counter. All pages share the same counter.
expected environment variables
local DENO_DEPLOY_TOKEN
: to be manually injected in the env before calling deploy
your redis credentials, needed both locally to be injected manually and on deploy entered on the project settings
live demo in deno deploy : https://astro-redis-counter.deno.dev/
.env
file STORYBLOK_TOKEN
loaded with vite loadEnv in config.jsstory.http
using VSCode REST Client and dotenv from .env
simple example where Middleware outputs log and sets an Astro.locals
variable consumed by the page to set the title in the layout.
tests
relative import within .astro file index.astro
: OK
alias tested OK with a custom path src/custom_assets
used from @/custom_assets
in .md although these two tests are identical, one of them takes the same directory path, the other a neighboring directory that a bit further away but both are strictly relative and have no special character
![Tree](./tree.svg)
note ![Tree](tree.svg)
will not work the ‘./’ is needed![Tree](../../assets/tree.svg)
<Image />
component now part of Astro core
content collections : OK. import image with checks
works ok, admin edit and save
dev to be replaced as follow
"dev": "tinacms dev -c \"astro dev\"",
usage is as simple as this
<Cache>
<Menu />
</Cache>
can also have different names that act as store keys
<Cache name="section1">
<Menu section="section1"/>
</Cache>
Note1 : This will cache all calls from all isntances, if the intended usage is a different cache set for every astro component file, then it is still required that the user gives a different name
for every instance, e.g. prefix component path (with e.g. a vite __filedir plugin )
Note2: This is caching production only for convenience during development, if caching is also intended during development (not recommended) then this line in Cache.astro
can be changed to remove the PROD condition
if(cache_has(name) && import.meta.env.PROD){
Test, see build log, both pages build are logged while the rendering of the cached component is logged only once
index> rendering index page
** rendering ** 'default' => cache_set()
page2> rendering page2
References
Astro example integrating lottie librarie with react
simple Astro example for integration of a Kute.js morph
Astro Theme for big doc websites. Hierarchical pages menu from files structure, table of content, Markdown rendered as CMS with Astro components for panzoom, 3D, links, interactive tables and more.
Main features :
screenshot :
Main features :
screenshot :