Static Sites are Simple
Static Sites are simple. They're just files, and mostly text.
Here's a PowerShell one-liner to make a really simple static site:
"<h1>Hello World</h1>" > ./index.htmlWe make static sites with whatever language we want, and we can publish them about anywhere for free.
We can can stick them on https://github.com/.
We just create a repository and publish them with GitHub Pages.
We can use a free server, like https://neocities.org or https://wisp.place
We can find the last server on the planet supporting FTP and put our files up there, too.
It's all just copy/paste.
There are plenty of frameworks to use, but today let's see how simple it is to make a static site without building a whole framework.
We can use GitHub pages to host our site for free, and we can use PowerShell to deploy it.
We only really need two files to get going:
- One GitHub Workflow
- One or more scripts
The GitHub Workflow
Our workflow exists to call our scripts and publish our page.
We want to put this file in ./.github/workflows/deploy.yml
This is just a standard GitHub pages workflow, with a few bonus points:
- It runs automatically about once a day, or on demand
- It maps the published url to
$env:page_url - It runs a script with the name of the workflow
- It allows you to set a repository variable with a Google Analytics ID
It's pretty carefully documented, but we don't have to read it: we can just copy/paste it into the repo and call it a day.
To make this step a bit easier, I've pushed this workflow to:
New-Item -ItemType File -Path ./.github/workflows/deploy.yml -Force -Value (
Invoke-RestMethod https://poshweb.org/workflows/deploy.yml
)Here's the workflow you'll be deploying
# Simple workflow for deploying static content to GitHub Pages
name: deploy
on:
# Runs on pushes
push:
# and run on a schedule
schedule:
# for those that don't speak cron, this runs:
# * At the first minute (`1`)
# * Every 21st hour (`1/21`)
# * Every day of the year (`* * *`)
- cron: '1 1/21 * * *'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, and cancel any in-progress deployments if a new one is triggered
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
# GitHub Pages use a single job, named deploy.
deploy:
# By using an environment, we avoid locking
environment:
name: github-pages
# and we can control where it is deployed.
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
# Check out our repository
- name: Checkout
uses: actions/checkout@main
with:
# Using fetch-depth: 0 to ensure we get the full history of the repository
fetch-depth: 0
# Setup GitHub Pages
- name: Setup Pages
uses: actions/configure-pages@main
# To Build Pages in PowerShell, we just call a script
- name: Build Pages
# set the shell to pwsh
shell: pwsh
# and then call any script we would like to build the page.
# By default, this can use the same name as the workflow
# (in this case, just deploy.ps1)
run: . "./$env:GITHUB_WORKFLOW.ps1"
# This approach makes it easier to logically organize workflow scripts.
# We will also map the page_url to an environment variable, so our scripts can access it.
env:
page_url: ${{ steps.deployment.outputs.page_url }}
analytics_id: ${{vars.ANALYTICSID}}
- name: Upload artifact
uses: actions/upload-pages-artifact@main
with:
# Upload the contents to the GitHub Pages artifact
path: './'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@mainThe site is built and deployed with .deploy.ps1
The Scripts
The scripts can be as complicated or simple as you want them to be.
So if we wanted to deploy hello world, all we need is:
"<h1>Hello World</h1>" > ./index.htmlWe can certainly style things up a bit. One easy way to do this is to create an array of content, and just output little bits of html.
@(
# We can just throw html into quotes
"<html>"
"<head>"
"<style>"
# and do the same for css
"body { max-width: 100vw; height: 100vh }"
"h1 { font-size: 3rem; text-align: center }"
"</style>"
"</head>"
"<body>"
"<h1>Hello World</h1>"
"</body>"
"</html>"
) > ./index.htmlKeeping things simple, we can standardize look and feel across a website with a little bit of layout.
Just make a layout.ps1 file and pipe to it.
# We can collect all input quickly with $input
# (but we can only enumerate input once)
$allInput = @($input)
"<html>"
"<head>"
"<style>"
# Feel free to change the style
"body { max-width: 100vw; height: 100vh }"
"</style>"
"</head>"
"<body>"
# By joining input with newlines, we're treating any pipelined input the same
$allInput -join [Environment]::Newline
"</body>"
"</html>"Then we can do something very simply, like convert a README.md into html and pipe it to layout.
ConvertFrom-Markdown -Path ./README.md |
Select -Expand Html |
./layout >
./index.htmlStatic Sites are simple.
This post is designed to get you started, and hopefully help you realize how PowerShell can generate static sites flexibly without a framework.
Please, try making some static sites with PowerShell. It's simple and fun.