Automate Screenshots With GitHub Actions

## Metadata
- Author: [[Colby Fayock]]
- Full Title: Automate Screenshots With GitHub Actions
- Category: #articles
- Document Note: ---
tags:
- #NodeJS
- #Playwright
- #GitHubActions
Author: Colby Fayock
Source: YouTube – Colby Fayock Tutorials
Reference: [Take Screenshots of Websites in Node.js with Playwright](https://www.youtube.com/watch?v=t95Jo1Wdljw)
date created: 2025-08-22 22:05
---
# Title: Automating Website Archives with Playwright, Cloudinary & GitHub Actions in Astro
## Table of Contents:
- [📝 Summary](#-summary)
- [📖 Main Content](#-main-content)
- [🗒️ Notes](#️-notes)
- [📖 References](#-references)
- [🗣️ Paraphrase](#-paraphrase)
- [📰 Newsletter](#-newsletter)
- [✅ Action Items](#-action-items)
- [🧪 Hypotheses](#-hypotheses)
- [📊 Methodology](#-methodology)
- [❓ Questions](#-questions)
- [🔮 Future Research](#-future-research)
- [💡 Implications](#-implications)
- [🧠 Learning Styles Assessment](#-learning-styles-assessment)
- [📊 Accessibility Assessment](#-accessibility-assessment)
- [🌍 DEIB Assessment](#-deib-diversity-equity-inclusion-and-belonging-assessment)
- [✅ Logical Validity](#-logical-validity)
- [🔍 DARVO Analysis](#-darvo-analysis)
- [🔍 SEO Evaluation](#-seo-evaluation)
- [🎯 Conclusion](#-conclusion)
---
## 📝 Summary
Colby Fayock demonstrates how to build a **website archiving system** that takes automated screenshots of web pages with **Playwright**, stores them in **Cloudinary**, and displays them in an **Astro app**. Using **GitHub Actions**, the workflow becomes fully automated—capturing, storing, and deploying updates at scheduled intervals.
---
## 📖 Main Content
The tutorial highlights a developer-friendly workflow:
1. **Screenshot Automation**: Using Playwright to open URLs and save timestamped screenshots.
2. **Cloudinary Integration**: Storing screenshots externally for efficiency and transformations.
3. **Astro UI**: Displaying images in a grid layout with metadata.
4. **Automation with GitHub Actions**: Scheduling recurring screenshots with cron and secure secrets.
5. **Continuous Deployment**: Automatically updating the website as new screenshots are generated.
### 🗒️ Notes
⏱️ [00:03](https://www.youtube.com/watch?v=t95Jo1Wdljw&t=3) Website archive setup
- Build with Playwright, Cloudinary, Astro, and GitHub Actions.
- Concept inspired by the Wayback Machine.
⏱️ [01:46](https://www.youtube.com/watch?v=t95Jo1Wdljw&t=106) Playwright setup
- Install Playwright (`npm install playwright -D`).
- Launch Chromium, navigate to URL, capture full-page screenshot.
- Save with timestamped filename in `screenshots/`.
⏱️ [03:39](https://www.youtube.com/watch?v=t95Jo1Wdljw&t=219) Cloudinary storage
- Install `cloudinary` SDK.
- Secure credentials via `.env`.
- Upload screenshots, receive secure URLs + dimensions.
⏱️ [07:30](https://www.youtube.com/watch?v=t95Jo1Wdljw&t=450) File system integration
- Use `fs/promises` for async JSON writing.
- Save archive metadata (URL, date, image URL).
⏱️ [09:25](https://www.youtube.com/watch?v=t95Jo1Wdljw&t=565) Astro integration
- Use `astro.glob` to import JSON archives.
- Render images + dates in grid layout.
⏱️ [11:26](https://www.youtube.com/watch?v=t95Jo1Wdljw&t=686) GitHub Actions automation
- Create workflow `.yml` in `.github/workflows`.
- Configure schedule via cron.
- Enable manual trigger with `workflow_dispatch`.
⏱️ [13:12](https://www.youtube.com/watch?v=t95Jo1Wdljw&t=792) CI/CD setup
- Run on `ubuntu-latest`.
- Use `npm ci` for consistency.
- Pass environment secrets securely.
⏱️ [15:03](https://www.youtube.com/watch?v=t95Jo1Wdljw&t=903) Playwright dependencies
- Install browser dependencies with `npx playwright install --with-deps`.
- Avoid deprecated Playwright GitHub action.
⏱️ [16:52](https://www.youtube.com/watch?v=t95Jo1Wdljw&t=1012) GitHub secrets + execution
- Store Cloudinary API key, secret, and cloud name as repository secrets.
- Test via manual workflow run.
⏱️ [18:32](https://www.youtube.com/watch?v=t95Jo1Wdljw&t=1112) Continuous deployment
- Every GitHub Action run pushes updates to repo.
- Astro rebuilds automatically on hosting platforms (e.g., Vercel, Netlify).
---
## 📖 References
- [Playwright Documentation](https://playwright.dev/)
- [Cloudinary Node SDK](https://cloudinary.com/documentation/node_integration)
- [Astro Documentation](https://docs.astro.build/)
- [GitHub Actions Docs](https://docs.github.com/en/actions)
---
## 🗣️ Paraphrase
1. Original: *“Playwright isn’t just for testing—it’s great for automating browser tasks like screenshots.”*
**Paraphrase**: Beyond testing, Playwright doubles as a browser automation tool ideal for capturing screenshots programmatically.
2. Original: *“GitHub Actions combined with Playwright and Cloudinary creates a simple but powerful automation pipeline.”*
**Paraphrase**: Pairing GitHub Actions with Playwright and Cloudinary results in an elegant workflow that automates screenshot generation and hosting.
---
## 📰 Newsletter
📸 **Automated Website Archives with Playwright + GitHub Actions**
Want your own Wayback Machine? Colby Fayock shows how to build a screenshot-based web archive in **Astro** using **Playwright** for automation, **Cloudinary** for storage, and **GitHub Actions** for scheduling. It’s a fully automated pipeline—run once, let GitHub keep track of your site’s evolution forever. Imagine using this for WordPress release landing pages, plugin changelogs, or even community site snapshots. Tutorial here → [Watch on YouTube](https://www.youtube.com/watch?v=t95Jo1Wdljw).
---
## ✅ Action Items
- Explore adapting this workflow to **WordPress.org** plugin/theme screenshots.
- Build educational content for contributors on **automated archiving + CI/CD**.
- Demonstrate Playwright use beyond testing (e.g., contributor dashboards, OSS docs).
- Connect Cloudinary automation to OSPO goals (e.g., transparent ecosystem metrics).
---
## 🧪 Hypotheses
- Automation reduces manual screenshot overhead by 90%.
- Visual archives increase transparency + trust in OSS projects.
- Astro integration encourages adoption due to lightweight setup.
### 📊 Methodology
- Compare manual vs automated archival time.
- Survey contributors on usefulness of archived site snapshots.
- Track deployment frequency improvements with CI/CD.
### ❓ Questions
- Could this pipeline be used to **audit accessibility regressions visually**?
- How might **archival automation help OSS governance transparency**?
- Would screenshots improve contributor onboarding (visual project history)?
### 🔮 Future Research
- Integrating **diff-based visual regression tests**.
- Combining screenshots with **textual metadata archiving**.
- AI-driven analysis of visual changes (layout, branding, UI patterns).
### 💡 Implications
- Could shape **new standards for OSS documentation**.
- May enhance **compliance + governance transparency**.
- Useful for **academic research on web design evolution**.
---
## 🧠 Learning Styles Assessment
- **Visual**: Strong (screenshots, Astro grid).
- **Aural**: Weak (no podcast/audio version).
- **Verbal**: Clear instructions + commentary.
- **Kinesthetic**: Hands-on coding exercise.
- **Logical**: Step-by-step code explanations.
- **Social**: Community-driven GitHub Actions feedback loop.
- **Solitary**: Self-paced implementation supported.
- **Naturalistic**: Absent (could add sustainability analogies).
---
## 📊 Accessibility Assessment
- Screenshots must include **alt-text** when displayed.
- Ensure **keyboard navigation alternatives** for visual UI.
- JSON archives should be machine-readable for screen readers.
- High-contrast Astro layouts would aid readability.
---
## 🌍 DEIB (Diversity, Equity, Inclusion, and Belonging) Assessment
- Tutorial tone is inclusive, avoids jargon-heavy gatekeeping.
- Could improve by highlighting **global hosting options** for Cloudinary.
- Neurodiversity-friendly: code is broken into **digestible steps**.
- Representation limited—examples focus only on personal projects. Could show community/educational use cases.
---
## ✅ Logical Validity
- **Deductive structure**: Screenshots → Stored → Automated → Displayed → Deploy
- Summary: Take screenshots on a cron schedule and display them in an Astro app with Playwright and GitHub Actions.
We'll walk through writing an automated script to take screenshots of a website, upload images to Cloudinary, display them in an Astro app, and automate the whole thing with GitHub Actions cron scheduling.
🧰 Resources
Starter: https://github.com/colbyfayock/demo-web-archive-starter
Code: https://github.com/colbyfayock/my-web-archive
Demo: https://my-web-archive.vercel.app/
Playwright GitHub Action: https://github.com/microsoft/playwright-github-action
Cloudinary Node SDK: https://www.npmjs.com/package/cloudinary
Astro Glob: https://docs.astro.build/en/reference/api-reference/#astroglob
Crontab: https://crontab.guru/
Vercel: https://vercel.com/ambassadors/colbyfayock
📺 YouTube: https://youtube.com/colbyfayock?sub_confirmation=1
🐦 Twitter: https://twitter.com/colbyfayock
📹 Twitch: https://twitch.tv/colbyfayock
✉️ Newsletter: https://www.colbyfayock.com/newsletter/
🎥 What I Use: https://www.colbyfayock.com...
- URL: https://www.youtube.com/watch?v=t95Jo1Wdljw&ab_channel=ColbyFayock
we're going to build a website archivethat uses GitHub actions toautomatically take a screenshot withplaywright upload it to cloudinary tocreate a nice static web archive app inAstrohey team I'm Colby fayock I make weeklytutorials helping to solve real problemswith the tools of the web you've everused the way back machine from the webarchive it's an amazing tool to be ableto find past versions of a website as asnapshot in history complete with allthe actual HTML that was delivered onthe page including all of its images nowwhile we're not going to actually take asnapshot of the HTML what we'll do is
take a screenshot using playwright so wecan have our small screenshot of Historyseeing how our website or maybe howanother website changed over time sogetting started the first thing thatwe'll need in order to actually displayanything on a page is the data inside ofmy Astro project I just created somecomponents and a little layout just toget the UI going but really all it'sdoing is dumping some content on thepage and what we'll be doing is placingthe images eventually inside of thisgrid that I have already set up on thepage if you want to follow along you canfind a link to the starter in the
description but I'm going to actuallycollapse that and I'm going to create anew directory I'm going to call thatscripts where inside I'm going to createa new file called archive.js where herethis is we're going to run the code toactually grab the information about thewebsite where each time I run this Iwant to create a few data pointsincluding a URL which I'm going to setthat tospacejelly.dev I want to create a newdate I'm going to set that to new datedate now and I'm ultimately going tocreate a new archive content whereinside I'm going to have that URL and a
date now on top of that I'm going towant an image but what we're going to dois use playwright in order to grab thatimage from the website and then we'regoing to upload that to cloudnary sothat we actually have a stored URL thatwe can use to show on the page sostarting off we're going to need playrayand while playwright is really great fortesting it's also great for being ableto automate other things inside of abrowser so inside of my terminal I'mgoing to run npm install playwright saveDev and at the top of my file I'm goingto import chromium specifically from
playwright or you can alternativelyimport Firefox or whatever browserplaywright supports and with thatimported the first thing I need to do iscreate a new constant of browser I'mgoing to set that equal to to chromiumdot launch where I need to actuallyawait this asynchronous command wherewith my browser I can create a newconstant of page and I can say awaitbrowser.new page and then finally I cansay await page go to and I'm going topass in that URL of spacejelly.dev nowbefore I do anything else we always want
to make sure that when we're runningthis we close our browser session so I'mgoing to run awaitbrowser.close but then in between our goto and our close I can start to takethat screenshot so I'm going to sayawait page screenshot I'm going to passin a path and this can really bewherever we want so what I'm going to dois I'm going to create a new directoryand I'm going to call that screenshotsand then we can make it so this path isgoing to be sent to screenshotsslash whatever we want to do maybe we
can use the new date where the date thatwe're creating in here is dynamically sothat we can actually use a time stampfor the file name so I'm going to saydate to ISO string and then I'm going toadd a DOT PNG at the end I'm also goingto say that I want to make sure it takesthe full page I'm going to say full pagetrue and at this point we can head overto our terminal and actually try to runthis and see what happens so I'm goingto run node scriptsarchive.js and then we can have a peekover inside of our screenshot folder
where if I look at it I now have my newscreenshot now that we have that imageinside of our file system we couldprobably technically store that in gitbut because we're probably going to havea lot of different images we probablywant to store that in somewhere externalas it's a little bit easier to manageand then we get a little of a lot ofother benefits such as optimization orother transformations to enhance theexperience so to do that we're going touse the cloudinary node SDK to uploadthat to a cloudnary account back insideof my terminal I'm going to run npminstall cloudinary at the top of my fileI'm going to import version V2 as
cloudinaryfrom cloudinary I'm then going to set upmy configuration so I'm going to runcloudinary.config we're inside I'm goingto pass in my cloud underscore name myAPI underscore key and my API secret nowI don't want to actually store thesevalues right inside of my file here sowhat I'm going to do is I'm going to addenvironment variables for all these sowe're going to need our cloudinery Cloudname our API key and our API secret andnow we want to actually be able to store
this in our environment variable file soI'm going to create a new file at theroot called dot EnV and then inside I'mgoing to set up a new variable for eachand every one of these where now we cango get our values for each of thesewe're right inside of my cloudinarydashboard I can find that cloud name APIkey in secret where let's first startcopying those over with the cloud nameand I'll paste that in and similarlywith my API key and my API secret nowjust as a reminder make sure to nevershare this secret value don't commit itinto git as it could compromise youraccount now by default since we're
running this in node outside of theAstro lifestyle cycle this file is notgoing to have any idea as to where tograb these environment variables so wehave to tell them where to find that andwe can use that using dot end is a toolthat probably a lot of projects actuallyuse under the hood but we can use thisif we're creating files or building ourown scripts in order to load theenvironment variables so I'm going torun npminstall.env and we're going to call thatsave Dev and back inside of our file I'mgoing to import everything as dot m from
our.m package then underneath theImports I'm going to say dot m config sonow our process.env should be availableand we should be able to see all of ourAPI Keys our secret and our Cloud namebut now we need to upload that image toour cloudery account so to start off I'mgoing to pull out this directory pathand I'm going to set that as constantscreenshot path that way we don't haveto write out that same thing again I'm
going to set that as that path value butnow I'm going to say constant results isequal to awaits cloudinaryoops spelled that wrongcloudinary.uploader dot upload and I'mgoing to Simply pass in that screenshotpath now it probably doesn't matter toomuch but I'm going to remove or removethe results to under where we're closingthe browser but now I'm going to headback over to my terminal and I'm goingto run that script again where once itcompletes we should be able to see ournew results including the public ID allthe information about that including a
URL and a secure URL which if we openthat up inside of our browser we can nowsee our new screenshot so we're going touse that secure URL and the width andthe height in order to add thatinformation to our image so let's sayinside of the image we're going to add aURL where it's going to be our resultsdot secure URL we're going to add awidth of results.width and a height ofresults.height and just to reassureourselves let's actually log out thisarchive to see what this looks like and
if we run it again we see this perfectobject where we have our URL our dateand that image that we just uploaded sonow we want to store this Arc archivedata inside of our file system so thisgets saved into git every time that thisis ran GitHub actions is going to runthe script and then save that file andthen inside of Astro we're going to pullall that data so to do this we're goingto use the node FS or file systempackage which is baked into the nodeenvironment now even though our scriptis separate from our application
environment it should be worth pointingout that we're writing the scripted nodeand Astro tries to not be environmentspecific so that it can support avariety of different environments inaddition to node this won't reallymatter too much for the node specificpurposes of our script but later when wetry to pull in this data we'll noticethat we're using different Imports toget Fs or FS light capabilities but fornow I'm going to import promises as FSspecifically because I want to use theasync await syntax and not use thesynchronous actions with callbacks so
promises as FS from fs and at the verybottom of our page we're going to runawait fest.write file we're inside we'regoing to specify where we want that filewritten or I'm going to say I want thisto be in a new archives directory andsimilar to what we did before with thescreenshot path I'm going to use thedate to create the file name so that weknow exactly the date that we're writingthis in but then for the file contentI'm going tojson.stringify our archive and this
probably is optional but I'm going toask also add null to so that it kind ofpretty prints into that file so thatanytime we want to look at theinformationanytime again it's going to be a littlebit easily readable rather than just aminified string now before I run thisI'm going to make sure I create thisarchives directory so that it actuallyexists but now let's run that scriptagain and once it's complete I'm goingto head into my archives where we shouldnow see that new Json file includingthat archive object so now that we're
actually being able to pull in that datalet's populate our page to start I ranthat archive script a few times just sothat we have a couple of data points topull in even though they're all going tobe the same but inside of my index.astrofile the first thing I want to do isimport all those new files from thearchive directory now as I was alludingto before we could technically pull inFS to grab that but there's actuallyways to grab that without being nodespecific now the nice thing is we canjust use astro.glob which is a globalinside of Astro in order to easily pick
up all those files so I'm going tocreate new constant of files and I'mgoing to set that equal to awaitastro.glob I'm going to pass in the pathto that archives directory and sincewe're in the source Pages directorywe're going to have to go up to andwe're going to look for archivesslash we're going to use a star so thatwe can get any file of a type of Jsonand let's console log out these files sowe can see what it looks like so I'mgoing to spin up my local developmentserver and immediately we'll see that
console log including an array of allthose files where we're able to see allthose Getters for the differentproperties but we can just make it alittle bit easier by using the defaultobject which is going to include all thedata that we need so I'm going to createa new constant of archives and I'm goingto set that equal to files.ap and foreach file I'm going to ultimately returnsome data but I want to grab that dataso I'm going to say constant data isequal to file dot default and thenultimately return that data I'm an avidconsole logger so let's console log that
out again just to make sure we're on theright track and indeed it looks like ourarchives array is full of those objectsof exactly the data we need so now let'sactually Loop through and put them onthe page so inside of my grid I'm goingto map through all my different archivesand for each of those Arc archives I'mgoing to return a list item where insideI first want to add my image a source ofarchive.image.urlI'm going to have my width and my height
and then once I have those I want toalso add my alt and we can say that thisis our screenshot and then it would behelpful if we have the date of when thatwas taken so I'm going to add thearchive.dates and just as an easy way toformat format it in a nice way I'm goingto say new dates and I'm going to say tolocalstring or Locale Locale local whateveryou want to say now if we pop into ourapplication we can see all of our
screenshots along with the date for eachand every one of those and while theactual date itself is going to be thesame for all of them we can see a slightdifference in the time for all of thembecause of course we did just run thescript a few times in the same day inorder to produce those results but nowlet's automate this where of course wedon't want to have to run that scriptevery single day where every single timeour site changes in order to get theseresults so we're going to use GitHubactions which is an easy way to automateworkflows just like this so inside of myproject I'm going to create a new foldercalled dot GitHub where inside I'm going
to have a new folder called workflowsnow inside there I want to create a newfile calledarchive.yaml or you can title thatwhatever you want to do we're here Ineed to give a set of instructions toGitHub on how I actually want this rannow the first thing I want to do is giveit a name or I'm going to call thisarchive but then I'm going to designatethe on parameter which is going to tellGitHub actions when I want to run thisand I want to run this on a schedule nowwhether you run crontab.guru to easily
try to figure out when you want to setthis up or you can take it to a bigbrain move where we're just going to askchat gbt when we can create thisschedule we're here it's telling us theexact schedule we need to run a crownevery single day so I'm going to justpaste that in which is going to be ournew cron statement and just to note thatthe server is typically on utc's time sothis is going to be midnight every dayat UTC time which I'm on the easterntime I think it's around 8 o'clock orsomething along those lines at night soit's not going to be your morning everymorning but we're going to actually add
one more parameter and that's going tobe workflow dispatch and as we'll seelater once we get into the UI this isgoing to be a way to manually kick offthis action so that we can test it butnow finally we're going to Define ourjobs and we're going to run a job ofarchive now there's a few requiredparameters like we need to Define whatkind of system or environment this runson so we're going to define the run onparameter and we're going to use Ubuntulatest and then we can Define the stepsthat we want to take inside of that job
now I'm just going to paste some ofthese in as I'm walking through themrather than typing them out but first wewant to use the actions checkout actionin order to actually check out ourGitHub repository we then want to runthe node setup script and this can bewith whatever version you want I'm using18 specifically right now which gives meaccess to things like the top levelawait which if you notice inside of ourscript we're using the top level awaithere where if you're running an earliernode you might not have the ability todo that but then once we have node set
up we want to be able to install all ofour dependencies so I'm going to runnpmci which is kind of like npm installbut it uses the lock file in order toinstall the dependencies so that youdon't have minor differences between theenvironment that you have locked andthen finally we can run our node scriptwith node scripts slash archive.js or ifyou remember inside of our script weactually set up a few environmentvariables for our cloudinery uploader sowe need to make sure we Define thoseinside of the environment so on thisparticular step we're going to Define an
EnV key and I'm going to paste this inbut we're going to Define every one ofthose different environment variablesfor every surface that we need inside ofthis node script now later as we getinto the GitHub UI I'll show you wherewe can actually add the secrets to addthose values but for now this is how weactually inject it into the script nowfinally we want to be able to take thatresult of the script and check it backinto our repository so we can use thispublish to GitHub action script which isgoing to do just that we need to pass inour GitHub token which this happens
automatically so we don't actually haveto worry about setting this up inside ofthe UI like our cloudinary secrets butthis is going to be able to allow us toeasily check that code back into GitHuband then finally because it by defaultsets to master as the branch name weneed to make sure we configure that towhatever whatever our main branch iswhich most of the cases will probably bemain now this should pretty much be ableto run our script safely but there's onething that I intentionally skipped andthat's how we deal with our playwrightdependencies now we have it defined as a
Dev dependency but having it as adependency isn't enough in order to getthe environment actually set up in orderto use it Microsoft actually had aplaywright GitHub action but what theyactually recommend now is not using thataction and what they recommend doing isusing the playwright CLI where they havethis command of running npx playwrightinstalled depths and that's going tohandle everything we need including thisexample that they have here where we'rejust going to Simply run this commandincluding installing playwright along
with the dependencies so after we runnpmci since we'll already have the otherdependencies installed we can run thatnpx playwright install with thedependencies and just to quickly pointout not sure if you'd notice I keptaccidentally deleting these values wewant to make sure that we specify ournode value and run npmci but now that wehave all of our steps defined I thinkwe're ready to jump into GitHub UI afteryou get all the code pushed up intoGitHub we have a few things we need toconfigure before we actually try to runthe actions so let's head over to thesettings tab where first of all let's go
to actions in general where we need toactually allow our GitHub actionworkflows to write those files into thefile system so we want to make sureunder workflow permissions that we addthat read and write permissions and aswe can see that GitHub token will thenhave that access so click save we'llalso want to make sure that we add thoseenvironment variables that we talkedabout before so under secrets andvariables head over to actions and herewe can start adding a new repositorysecret for all those cloudinaryvariables including the cloudery API key
and the API seeker and the cloud namebut once we have all these inside openour account and saved we can thenfinally go over to the actions tab wherewe can now kick off our new archive bynavigating it to it inside of theactions section here and then like Imentioned before since we have thisworkflow dispatch trigger we can goahead and manually kick that off byrunning that workflow after a second ortwo you'll see it pop up here and youcan even navigate to it so you can seeeverything that's happening inside of
that workflow including all those stepsthat we set up and once we land on jobcomplete if we now head back over to ourcode directory well it's going to kindof be hard to disturb determine what'swhat since we just ran that script abunch of times we should be able toparse out these timestamps and see thatthese are all 19 so we have our 20 butwe even see automated published therewhere if we look at the screenshot thiswas just taken inside of our GitHubaction workflow where now if we try torun the application it's going to pullthat in so let's test that out where I'm
going to run gitpool where excuse me Ineed to actually set up my Upstream Ialways forget to do that so I'm going toset it to main I'm going to run get pullagain we can see that those files werepulled down so let's spin up the devserver and if we scroll down all the wayto the bottom we now see that we havethis time stamp of four o'clock whichfrom my time right now is about correctfor when I actually ran that GitHubaction now the cool thing about usingGitHub actions as a mechanism for thisno matter if you're deploying to verselor netlify or wherever you have set up
with automated deployments from GitHubthis is going to trigger a new deploy soit's already always going to update thatnew landing page anytime that you havethis automated push pulling all thesetools together including runningplaywright with GitHub actions uploadingit to cloudnary and then actuallydumping that on a page with Astro givesus a lot of powerful features for beingable to have simple use cases like thisor pull it into more interesting usecases like data collection well maybebecause our site probably doesn't changedaily or maybe if your new site it does
it might not make sense to run thisdaily but maybe weekly or monthly thenice thing is you can configure thatQuran to whatever time stamp you want ifyou want to take those cloudery images astep further and take advantage ofdynamic Transformations check out myvideo where we optimize and dynamicallyresize with cloudery make sure to givethis video a thumbs up subscribe andclick that little notification Bell forfuture web dev content thanks forwatching, Automate Screenshots With GitHub Actions, Colby Fayock, 01gyd171tcm94z6exkc5zx82p9.