The theory versus the practice of “static websites”
utcc.utoronto.ca
utcc.utoronto.ca
I no longer think about the server or the CMS. I no longer need to keep it updated. I got rid of the heavy database and the elaborate caching setup. Now it's just a static file server. If it was just the blog it would be even easier to host. The website is more reliable and requires virtually no maintenance.
The best part for me is that I can work offline. It's just me and my text editor, so even my tiny Macbook 12" feels blazing fast.
Version control is also incredibly valuable. I can review my changes or roll them back. I can also find/replace across the entire content with regex. Text files are easy to work with.
I wrote about how it feels and why it works here: https://nicolasbouliane.com/projects/ursus
Same here, I'm using Sphinx and loving it !
I very much appreciate the ability to get all nitty gritty whenever I want to implement something "special" like the Favorite Git Aliases post which when edited gets turned into a .bash_aliases file and pushed to Gitlab and mirrored to GitHub! :D
For those curious it's over at https://jdsalaro.com , I don't have much details on my stack or why but I will be documenting bits here and there. I did start with my Markdown and Myst Cheatsheet for Sphinx (https://jdsalaro.com/cheatsheet/sphinx-myst-cheat-sheet/) and how to load the environment.pickle (https://jdsalaro.com/howto/sphinx-load-environment-pickle/)
I love your idea. It's very clever!
Fast, complete in what it does, to the point.
[ IMHO <cough> it could use a section on TV Series and Movies set in Berlin past and present with a quick rating on how realisticly they portray actual Berlin ... but that's just me :-) ]
Most servers in the world use a constant amount of electricity, regardless of load. Generally the way to make DCs more green is to build them around a renewable plan with batteries (that they already need). Save for the fact that the whole thing is made of rare earth metals and lead, and you've got yourself something pretty green.
That seems unlikely. Even if you disable frequency scaling, hlt uses less energy than a full pipeline of avx. Disks use more energy when reading or writing than idle (although for spinning disks, if they're not idle enough to spin down, the difference isn't that much)
Datacenters do tend to have a lot of batteries, but the runtime expectation is pretty small, 5ish minutes takes a lot of batteries and is enough for the onsite backup generator to start amd warm up. It's been a while; maybe those aren't lead acid anymore, but they used to be. Stationary, weight doesn't matter, volume isn't super important, cost is important, leads towards lead acid, IMHO.
I try to keep things simple. Simple websites are fast and reliable. Turbo seems to be a departure from that. Since the heaviest part of my pages is the text, it would not help much.
Would be great to make the tech more accessible to those without the skills to recompile and deploy. It's such a fast and affordable way to build websites, but existing tools like Hugo assume a lot from users that can put the tooling out of reach.
(Enjoyed your write-up too. I wrote the original version of html-to-markdown that you used in your migration; it's great to see it's still useful.)
https://tina.io/blog/Introducing-Editorial-Workflow-Features...
We need more like this that doesn't require a SaaS-backed "business or enterprise plan", though.
Totally agree for this narrow use case. But you're also correct that if you're a startup with a marketing site--going the Gatsby/Hugo/etc. route is a total disaster. Have seen so many technical founders make this mistake.
What happens is you realize, crap, my team needs to publish content for SEO and build new landing pages...and they aren't able to do my esoteric Git + Hand coding + Markdown/Front Matter + build process steps. So then you get sold some convoluted "HEADLESS CMS," which claims to solve your problems, but is actually a total freaking nightmare to setup and maintain (god forbid you ever want to change anything).
Have witnessed this charade more times than I can count. Seriously, just use Webflow. I know HN is highly disgusted by the idea of something being marketed as a "no-code" tool. But Webflow basically is a static site generator + headless CMS, just with a UI layer for non-technical folks. When you click publish on updates to a Webflow site you're basically automating the recompile and deploy steps.
Yes, they have their place but it's far morw niche than the hype wants you to believe.
* The UI layer is complete and total garbage. It is unbelievably slow and clunky and it makes doing anything with it a chore.
* The UI is complicated enough that it would be easier to teach the non-technical folks to use markdown.
* Uncomfortable amounts of lock-in. You can export your entire site of course but retrieving your "CMS" records is not so straightforward.
* If you need to do anything interesting, the UI benefit is gone, because now you get to write code AND use their awful platform.
* Expensive, with a recent price hike with no increase in the functionality or quality.
The recompile and deploy steps can be automated in ways that don't require hitching yourself to this behemoth.
For me, this is another way of keeping everything in a monolith, and which requires a lot less context switching. If I’m building a feature and I want to create marketing or support content for it, it’s all right there in the same repo. I just create the markdown files I need, commit them to the repo, and I’m don.
The thought of switching between a static content site or something like Webflow just seems silly for a small team or project.
Of all the problems we’ve had running a website, Hugo has not been one of them.
Originally, hand-writing HTML was a supposed-to-be-accessible-to-non-technical-users way to make a website.
Until the late 1990's, HTML was used sort of like Markdown is used today.
A secret reason why I like to push markdown workflows is that you can't deviate from the site's overall look and feel. Focus on your content, hit publish and it will look good. Even if we change the site's look down the road, the content is still going to be fine.
It gave the internet character and flaws. Now it feels like everyone limits themselves to publishing nothing but perfect images of themselves.
Hit Count: 3,404
For example:
Wikipedia only recently perfected their Visual Editor in a way that made me feel comfortable using it, but it's still a situational decision whether I use VE or edit the source directly.
And at $dayjob I am accustomed to poring over raw MarkDown, due to lack of a viable WYSIWYG application.
All-in-all, doing a static site has allowed me to learn so much more about html and other basic web technology than I think I would have ever gotten from a Wordpress or similar site. The biggest downside thus far is that I wanted to start a sort of Wiki-style knowledge base for users to contribute in my particular niche, but of course the static aspect precludes any user editing. I use that area of my site as my own knowledge-base still, putting info there that I reference all the time at my day job. For fun the other night, I got sucked down the rabbit hole of adding Disqus comments too. I don't expect anyone to ever use them, but instead was just learning about how to do it.
[0] The site is at https://ShieldDigitalDesign.com if anyone is curious to see what a dumb EE can do with a Hugo-generated site hosted with Fastmail.
On the other hand, it's great for me, because I don't need to babysit a database or maintain hosted software. I can go on vacation and not worry about anything.
E.G. The workflow might be updating a database on the local system and a set of affected pages published. Or it could be modifying comments within source code files and a Makefile like regeneration of document files that are then rsynced to a host elsewhere.
If there are user specific portions for some reason those would act more as a real application in sideband to the data, rather than a synchronous (and render blocking / load slowing) detraction from the experience.
Unless you constantly fiddle with the site design, the site and HTML generation should really be on devices and the whole thing should take less than a second to generate.
Unfortunately as other comments have said the current way of Github / Version Control / Text Editor are very much tech / Programmer focus. We need something like a hosted version of Wordpress, back to the old days of Dreamweaver / Frontpage.
It has (used to have? Can't find them on the site now) pre-packaged binaries that you would drop into a folder structure generated by the technically-minded person, and the content editor can simply click on that binary, which opens the backend of the CMS in the web browser, make changes and click deploy.
I suppose you could build this on top of Django as well, with django-distill, putting the distill-deploy step into the Django admin and then compiling that to a binary.
Previous generation 970 claims to deliver 50k IOPS
I don't have the link to benchmarks at hand right now, but there was a review running CrystalDiskMark on these drives and the 4k random performance of the Optane drive was more than 10x the 980 pro. For servers delivering tons of small-ish files, that's exactly the use case.
Can't you use regex?
_[^_\n\r]+_
edit: I think double underscores are easier, you should be able to use __.+__ and there's no reason to have to avoid matching single_underscore words.
On the other hand, now I can use any search and editing utility I want, not just whatever my CMS provides. A good example is adding a space after the § character, which I use a lot. It would take five seconds to fix it across the website.
A good text editor theme makes a big difference. I fine-tuned an existing Markdown theme for Sublime Text to better highlight the markup, especially headings.
weird that broken search basics are not an issue, you extol the virtues of site search in your blog, that engine is capable of matching "shcfua" to "Schufa". Markdown, on the other hand, fails in search long before getting to fuzziness
> § character, which I use a lot. It would take five seconds to fix it across the website
True, and then forever to hunt down those few instances where § was used in a quote or something and should not have been fixed
> I fine-tuned an existing Markdown theme for Sublime Text to better highlight the markup, especially headings.
I "highlighted" most of text markup to make it invisible, a bold text is already visualy bold even in Sublime, why woud I need an extra __indicator__? And heading size is also the best highlighter, which plain text editors don't do
But yeah, I wish there were Sublime-level tool for rich text so you wouldn't have to compromize like that...
I see the diff in Sublime Merge before committing, so I'm far less likely to break something. I used to make so many errors because the WYSIWYG editor caught a random keypress.
Personally, I want those indicators to be there. I'm editing the text and the formatting. I want both to be on the screen.
Frankly I don't need to convince you that this is better. I work with this 40 hours a week and it's better for me. Feel free to take a different approach, but also accept that this approach is tested and true for me.
Also, formatting is there on the screen - in the form of formatting!
So do you change text font size in CSS separate from the content or within markdown since it's part of text and has no value when separated?
> It's part of the diff
it doesn't have to be part of the same diff. In your current workflow you can't separate it by design
> I'm not sure I understand what you're getting at.
It's pretty simple - content diffs are very valuable, markdown pollutes it
May I ask how the revenue works? I just like that it’s not polluted with ads.
https://allaboutberlin.com/guides/movies-set-in-berlin
There's a typo in the TOC. … is being rendered literally I'm guessing because the ampersand is escaped accidentally.
Also a few you might add to the list: Berlin Alexanderplatz (1980), Possession (1981), Gotcha! (1985), Suspiria (2018), Undine (2020)
And yes, that page is woefully outdated. It's also missing One Two Three, Babylon Berlin, Dark (kind of) and many more.
Many apps need VCS, not a database, and CMS is one of the clearest.
A static site web server can only ever, worst case, be induced to serve the wrong files. And you can mitigate that by making sure the only files you put on the server in the first place are ones you want to serve.
A dynamic site can be induced to run code. It can be induced to return the wrong data from the database it has access to (passwords for example). It can be induced to modify data.
Wordpress breaches happen all the time. Nginx breaches don’t.
Except when someone forgets to append a trailing slash on a location block with an alias directive.
Technically there's no web site that doesn't "run code". There's always code involved. It's code all the way down, from the web server to the file system drivers, the operating system and so on.
While it's true that static files reduce attack surface, we need to think deeply why is that, and design intelligent dynamic systems that have the security of static ones.
And ultimately it's about input, and how input is treated. It doesn't matter how complex code you run, if you accept no input, you can't attack that system. Of course with no input you can't even figure out which page to show. So there's always input, even for static sites. But I'm trying to point our attention to what's the major distinction here.
But this is a side channel attack, right?
The point is that a static web server does that and only that. A dynamic web server is one that does that and more.
That's because the nginx inputs have a much more homogeneous type than your random django-based system.
I'm not sure there's anything you can learn from that. Some use-cases just lead to more secure software than others, and this is a completely non-actionable piece of information.
I don’t tend to worry about the RCE risk of hosting files in an S3 bucket behind a cloudfront distribution. That’s someone else’s problem.
As mentioned in the article, every dynamic website will also need some static assets (the .js files, images, etc.)
So, it seems like a dynamic website will always have greater attack surface area than a static one, by definition. It will have all of the static site surface area, plus some more.
----
I wonder if there is room for a language that is not as general as JS, but can still be used to add dynamism to a website. So, you don't have to be stuck in the "it's Turing complete, so we can't be sure it's well-behaved before running it" situation.
Perhaps CSS is kinda turning into that, these days.
Though maybe CSS will become Turing complete too, at this rate (:
You could theoretically never need to “update” a static site. There’s not even really a concept for it. Unless the target changes HTML versions, I guess.
While I do agree a static site has a smaller attack surface, I think it’s more that nginx has way more eyes on it and a much slower development rate than your average custom configuration of WordPress plugins.
Because if you were to build your own static web server, your first version would probably more susceptible to attack than a stock WordPress installation.
The semantics of that abstraction are that requests come in to a specific path with headers and a body, and then responses are sent back out with headers and a body. The intermediate networking details like TLS are hidden. In fact, more and more things are being hidden from the developer, with most modern frameworks automatically managing authorization sessions and request headers. Within that abstraction, the standard "static doesn't depend on request/state, dynamic does" is pretty clean, but it does rely on the semantics provided by the abstraction.
It's a little bit like TCP being a connection-oriented protocol over a fundamentally packet-based underlying infrastructure. I can use TCP for applications that require stream-like or packet-like data transfer. Then you could argue that "in reality, the distinction doesn't exist because it's built on IP which is packet-like". Sure — but you'd be on the wrong layer of abstraction.
That's not to say the article doesn't make a good point. As developers, we should certainly always keep in mind the underlying statefulness of "stateless websites". It's always good to know your abstractions a few layers deeper than you think you need.
It's still fast and efficient; when one of my blog posts was #1 on HN last week, my friend texted me "good luck, hope you have Cloudflare set up". I don't, but the load average on my 2 core, 1GB memory VPS never exceeded 0.15.
- For most of the site, hand-jamming HTML works fine, because I have a small number of pages outside the blog.
- For the blog, I wanted easy authoring, thus Markdown. I figured if I rendered it on each request, I wouldn't need to make a separate tool to regen stuff, I could just build it all into the server; any changes I made to the markdown would be instantly reflected on the site.
I wrote this in Go at a conference in 2011. Hugo didn't exist yet or I probably would have just used that.
edit: I initially wrote this on Plan 9, and it's so old that there's still a mkfile invoking go/8g and go/8l individually to build it. It's 265 lines of code, which does the static content, generates the blog stuff (including creating the blog "archive" page on-demand), and manages multiple domains so I don't have to invoke e.g. apache to use the same host for multiple sites.
Made perfect sense in 2001 for building a static website where you happened to want to have e.g. a comments section on each blog post. And this kind of PHP was cheap enough that even your ISP was usually willing to let you slap some of it up on your /~userdir/ and point the public Internet at it.
I think after bouncing around with Node and the flavor-of-the-week static site generators, I might be going back to PHP for my personal sites.
Which is insane. If you told me I'd be heading in this direction anywhere between 2 and 15 years ago, I'd think you were lying.
All I really need are template files. I could use iframes but that stinky technology actually deserves its stink.
Yeah, if you launch Threads you need whatever it is Facebook does to scale. But for a regular read only site? You don’t need to spend very much at all.
E.g. nothing will ever beat a dumb file server with a cdn in front when it comes to simplicity and scalability.
The only thing you can make use of is the design and the actual content.
It was great. Until the webhost took away PHP anyway.
If you use Jekyll as static site generator and GH Pages for hosting, it even works out of the box (eg no GH Action tinkering needed, just flip a switch in the GH project settings)
But arguably, a local static site generator workflow works just as well (convert to html locally and upload those files to web hoster instead).
You might want to store user-submitted content in a database, for example. Or you might want to do authentication. You might want to provide full-text search in a multi-gigabyte dataset. You might want to provide an interface to something which can't be accessed from a web browser. You might want to validate user-provided input.
All of those require custom code running on a server. So now you have to take whatever data you have on the server, translate it into a well-defined custom transfer protocol, send it to the client, translate it back, and finally turn it into html. And the same for the other direction, but now you suddenly have to do input validation on both the client and the server to prevent anyone creating a custom client from doing anything malicious.
Or you can just turn it directly into html on the server and be done with it. It's a lot less work, and provides basically the same experience for most applications.
PS: how complicated that is all depends on the library ecosystem IMHO.
If you haven’t used the device integration features of OS X and iOS you are missing out. Cut and paste is very, very useful.
* If you have some secrets that need to stay hidden (e.g. database passwords, API keys, encryption keys, etc) then that needs to be processed by code that lives on your servers. If all your code runs on the client, then there is always the chance for an attacker to discover those secrets.
* It is often easier to present a smaller, limited API to the client to reduce the surface area available to attacks. For example, if you let the client connect directly to your database, you need to make sure that that database is correctly secured, that the correct permissions are there, and that nothing can go wrong. But if you just give them a list of books, or films, or whatever your app does, then it will be harder for them to break through that defence. (And if they do manage that, you should still have the database set up as securely as possible to provide an additional layer of defence.)
* A site often feels more responsive if the initial load is served as one single chunk of ready-to-use data (as opposed to serving the application, showing a loading indicator, making the necessary data fetches, then showing the data). Even if they take the same time the first option often intuitively feels quicker to the user.
* Leading on from that, it can often be quicker to load things up front, just because the server that's responding to the user is probably sitting next to your database and any other servers it needs to talk to. These network calls are also much more reliable in that sort of context. If you push all of the processing to the user, you're going to have to handle the slower and more unreliable calls.
* The server will probably be a much more consistent platform than user browsers. Browsers are a lot better these days, but there are still lots of slight differences that you'll need to be aware of. If you have control of a server, though, you can specify the exact versions of every tool, runtime, etc that you need, and be able to update things more deterministically.
Fwiw, these aren't all true all of the time, and there will be exceptions. I work primarily on frontend applications, and there's a lot of value in a well-designed application that does the majority of work, if not all, in the browser. But this is typically only true for fairly complex web apps, or projects where some amount of rendering has to happen in the browser whatever happens.
Why is that supposed to be better?
Especially the ones predating PHP. Also a couple of the most popular open source Perl ones. I remember Matt's wwwboard working like this, for example.
Some of them didn't. But A LOT certain did.
Now, for a forum, I’m not sure this is a good idea, unless you have a super fast optimised build process. Even then, the delay in build is not what people expect from a forum. But the OP is not suggesting pulling a 100mb db down into the browser.
I know how static sites work, I run dozens of them for people.
I don't see how using WASM improves the situation any.
One can perfectly store data as JSON or even Markdown itself on separate files but do the templating in the frontend, for example.
Pretty easy and doesn't require downloading 100mb of data.
Because the generation is done once, and it is darn quick. After that all of the numerous advantages of a static page still applies from a users perspective. The resource use is many orders of magnitude less and the page is much more responsive. The user experience is vastly superior, we haven't cared about that in the last decade.
And how much skill you have to not mess up basic browser functionality.
As a reference point, GitHub still breaks the back button for me like 40% of times when I'm navigating their source code (me using Chrome on OSX because I only need to do this on my work laptop). I don't even know how they manage to do this.
In my experience, sites that generate HTML server-side tend to feel faster and more reliable than anything that depends on rendering client-side. Loading a booru with 50+ images per page with a cold cache in my browser, always feels quicker and more pleasant than loading text-only GitHub pages that should already be cached everywhere and haven't been modified for days.
Unfortunately, I get the feel that with the release of v13 app router, they don't give the static export feature enought love. Features from the pages router were dropped for static export (shallow routing, static rewrites/redirects). I fear they are dropping static export all together in the future, as you don't need their comercial vercel offering at all when using static export.
I personally don't care for the size of my node_modules folder, storage is cheap. Plus, with a yarn.lock or package.lock you don't have to care about npm dependencies, if you don't upgrade any, your simple `yarn install && next build && next export` will always produce the same result for years to come. The actual export output of NextJS is amongst the smallest you can get - you also get a nice summary of how big the initial load is for every route.
Everything is chunked per route, all js chunks and assets contain their hash in the filename. That is why you can serve all of /_next/static with the `Cache-control: immutable`. This means if you don't update a section of your app, there is not even a need for the client to send GET requests with the `If-modified-since`, means: No additional roundtrip for any chunks. Preloading can be configured, by default its on-link-hover - that is, if your user hovers over a hyperlink/route, nextjs will already fetch the required chunks for that route before the click happens.
Yes, NextJS is not competing with Hugo or other static site generators. It is aimed at tech-savvy people, and only for webapps that will require programming JS.
I did a migration from pages router to app router for my static-export project. Btw both are still present in v13, you can pick whichever you want, but long-term the pages router will be gone.
With static redirect/rewrites I mean the feature in pages router where you put in the "redirect"/"rewrite" statement in your next.config.js. These will be respected and work in a static export environment. If you try to perform a static export using app router, it will error and tell you that you have to remove "redirect"/"rewrite" from next.config.js and it is no longer supported.
Yes, you could use a middleware for redirects, but that is exactly my point: Middlewares do not work with static exports, they are middlewares for the server-side next server. Which is not present in a static export (and requires running your own server again, or use vercel's offering).
The same holds true for shallow routing for static exports, it is a feature still present in pages router, but not in app router. There is a GH issue of a lot of users complaining about this, but no feedback from the maintainers whether this is planned to bring back: https://github.com/vercel/next.js/discussions/48110
For shalllow routing you are probably right (I don't use them much so I can't tell much, but I do have a few critics regarding app router too) but regarding rewrites, an URL rewrite has to happen in a server so I still don't get your point. What was removed in v13 is the shortcut via next.config.js not the ability to do rewrites/redirects which can be done easily using middlewares or whatever your host provides. It's also recommended to setup i18n yourself in a similar fashion instead of using the built-in config, something that I've been advocating for a long time (https://github.com/vercel/next.js/discussions/17631#discussi...).
Gaeron example or the comments below show how to handle dynamic routes rewrites via nginx for instance.
But yes, you will need to add support within the webserver like nginx. A simple modification to `try_files` will do, and is probably present in most deployments anyway (because you will want URL routes like example.com/news instead of example.com/news.html). I think they just not considered that feature in the design of the app router. And I also don't think it is technically impossible to apply client-side redirects/rewrites within app router.
The pages router is not deprecated. It will be supported for quite some time still, and is even receiving new features.
Then I switched to PHP, and then Python, and now back to static using Jekyll.
It's just so much better, when possible to use. Aside from SSL certs everything can be fixed on your timeline. Compare PHP breaking something on upgrade, where you need to fix it immediately, and the site is down until you're done.
Static site, even if the generator breaks, fails... well... static. If you don't need to post anything new, then you don't have a problem.
And if the server explodes, you can just ask a friend to host some files. Not "hey, you run PHP version X with settings Y, right? And postgres?".
(Some friends maybe even say "no, I don't want PHP on my machine")
I call it the Baked Data pattern: https://simonwillison.net/2021/Jul/28/baked-data/
The key idea is that you deploy a full read-only copy of your site's data as an asset bundled into your application.
This only works for sites that don't constantly have updates, since you need to re-deploy the entire site when anything changes (just like a fully static site).
Benefits are you can deploy to inexpensive dynamic scale-to-zero hosting (like Vercel), you can handle any amount of traffic by running multiple copies of your app and if the app crashes your host can just restart the application automatically.
So, in compiled binary executables it was not uncommon to include encoded binary resources, like files or images. Not tons of them, because they would explode the size of the executable.
For example, for C or C++ https://github.com/graphitemaster/incbin
So here's the interesting part - we decided to build executables in a way that data in those executables could not be changed (makes sense since it's compiled and the compiled code runs on the machine, and for security reasons).
That said, think about what a container (e.g. docker) is. A running container is kind of like a packaged executable, except it also has a filesystem.
So if you pack data (which can be modified and runtime!) into a container, it's a similar concept to an embedded resource in an executable, except it can change.
Now, in a container, any changes made to data at runtime inside the container won't persist unless the container is given persistent storage.
What I've been wondering lately is why we didn't invent some kind of single "executable plus volatile data space embedded within the executable", so that programs and data (say, a database) could couple together into a single file.
Just a musing but tangentially related to your "baked data" - basically, embedded resources in executables just embeds the encoded data right into an executable.
For scripting languages, of course, we can just make a script file that contains a variable with the encoded data as base64 directly.
For the latter 2, it's only good for relatively small static data of course, but it would be interesting to build tech that somehow lifted that constraint of executables.
> So if you pack data (which can be modified and runtime!) into a container, it's a similar concept to an embedded resource in an executable, except it can change.
> Now, in a container, any changes made to data at runtime inside the container won't persist unless the container is given persistent storage.
> What I've been wondering lately is why we didn't invent some kind of single "executable plus volatile data space embedded within the executable", so that programs and data (say, a database) could couple together into a single file.
Things like this have existed before, and I presume still exist. For instance, before MacOS X, applications for Macintosh for (vaguely) similar to "application bundles. Leaving aside the technical differences of implementation, classic Macintosh applications had a "resource" store that included code and 'static' data (pictures, text, whatever) but could be modified by running program. Changes could be persisted without using any other files. In practice, changes were often persisted elsewhere, be cause if a fault occurred during modification, the executable could be corrupted, and because this made things like resetting to defaults easier (by deleting or moving an external preferences file, for example).
I've tried to use this library but found a bug: https://github.com/graphitemaster/incbin/issues/61
Is it more that your approach stores stuff in sqlite and builds from that, rather than markdown files? That seems to be the only meaningful difference I can see compared to normal static sites with backend/server-side functionality?
The key idea here is that your server-side stuff is completely read-only - so comment systems aren't supported - because the server-side data is treated as a deployment asset.
Have you used platforms like Vercel? Their one big limitation is that you can't use persistent storage with them - if you want to talk to a database of some sort you need to add an extra database vendor.
The baked data pattern works around that by bundling read-only data (usually a SQLite file) with your deployment.
I don't want to piss on your parade here - perhaps I just don't get this pattern - but isn't this all of the downsides of a dynamic site but without any of the benefits? You are still running slow server side stuff that relies on doing per-request database stuff and all the complexity and security headaches that go along with it (upgrading PHP or Wordpress or whatever), but with none of the benefits of server side functionality and databases (i.e. it is all read-only).
Correct me if I'm wrong but Decap CMS (previously Netlify CMS) runs in the browser and makes reads/edits via GitHub which can then trigger rebuilds and deploys, but it still needs a small server/proxy I think because CORS stops your browser communicating directly with the GitHub API. Netlify hosts a GitHub backend that proxies requests for you but now you're tied to Netlify and their pricing plan changes.
GitLab and BitBucket will have the same issue I think: https://github.com/isomorphic-git/isomorphic-git#cors-suppor...
Is there a simple solution here with minimal configuration? I guess you could use a browser extension to selectively relax CORS but that's not ideal.
It feels like a Git-based static site generator with a CMS that has Markdown editing and live previews that runs in the browser with minimal hosting/server restrictions would work for a huge number of small websites and blogs.
Decap-CMS demo here: https://cms-demo.netlify.com/#/collections/posts
currently this extension works on locally installed version of VS Code on you laptop,but doesn't work on Github Codespaces.
if we could somehow get that to work (within the free tier of github codespaces, with reasonable limits on usage time) i think it would be a winner -- completely online version controlled setup with no dependency on a dev environment installed on your own machine, while serving static sites off say just S3, and still getting a full CMS experience.
This problem is completely solved by Surreal CMS [1]. Make your website anyway you want, connect surreal by FTP and let the user/client edit what you permit them to edit. The cost $12 per month is dirt cheap for never having to worry about it, and giving non-tech users a total WYSIWYG editor.
You never know when they'll change their pricing, like when Forestry was recently deprecated in favour of Tina CMS with more limited free plans.
put up a "fire and forget" site using any kind of PHP or (perish the thought) wordpress (assuming self hosting), and if you dont check that site a few times a year, it will be all Russian porn ads before you know it.
Further, rendering of text and images is handled by client configured applications that change - with the content fitting into client specified configurations
Given that, if you want your content to be fast to access and simple to maintain over the longest period then:
1. Provide the smallest possible amount of bytes to the client that completes the communication task
2. Format the data in a way that will remain supported by the most clients over the longest term
It’s fun to play with different setups for a variety of use cases and server side rendering, but history shows that the most reliable design pattern prioritizes clients being able to consume and render data as quickly and clearly as possible.
I’ve never found a simpler way to do that than a file server hosting static .html files with text, svgs and pngs.
FWIW for my personal site, I run my own web server, which is incapable of running server-side code. It just copies files to sockets, nothing else.
That said, as the second article points out, static vs dynamic can still be a useful abstraction layer, as static servers like nginx and Apache are so solid that you can usually just treat them as part of the basic HTTP infrastructure.
There is obviously something that must serve the content but it is not necessarily you.
Of course it took us a bit more work to polish it, but 90% of the work was hers (I helped with things like setting up Hugo, Netlify, writing some template code, fixing the CSS on mobile, etc).
The biggest pain point of making a static website is just wrangling the generator. We wanted an image gallery with a couple selected works showcased on the front page, and the combination of various Hugo features to achieve that exact effect turned out to be non-obvious. There was probably a way to make it simpler, but we haven't found the time to find it.
I think most non-technical people can easily get the first 90% of the work done by themselves with the currently available tools, it's just the other 90% where you find yourself struggling ;)
-Github account
-Familiarity with markdown (learn more here)
-Ability to run node.js and npm on your computer
-Optional: a domain name."
Definitely not the same as using Wix, and definitely not usable for non-technical people.
I think it's something every web developer should be aware of. Static is indeed a lot simpler than dynamic.
I've wrote more about it over here[2] (SSG = static, SSR = dynamic).
I can definitely hand generate the small amount of content in it and could work out the contact form easy enough, but having no experience with websites don't know where to start with things like hosting, etc.
Hopefully can learn something here.
Highly recommended if you want a low maintenance rock solid transmit only website.
Besides my blog, Pianojacq.com is set up much along the same lines, but there is a major difference, it interacts heavily with peripherals (MIDI) and needs a database (locally, not remotely), the end result is a highly interactive but still 100% static website.
For a personal blog the idea of going real old school and editing the files (maybe a simple bash script to bulk update menus etc.) is appealing though. Since my metric is “can I come back in a few years and figure out what I did”
I stupidly started my API interface as just a million unstructured JSON endpoints, each one with its own requirements / json structure / cache strategy / etc. The amount of work that essentially feels like boilerplate is mind-numbing.
I haven't looked around for better alternatives very much, but I would be greatly interested in technology that makes the client/server boundary feel nonexistent, without needing to totally upend your current stack with a brand new framework like Next or something. Just a drop-in library that makes the server feel like another clientside API. I have no idea how that would be done without excessive coupling of the client/server though.
I've found random endpoints works reasonably well tho. You can change the server response and it only affects one client page. Easy to maintain.
If you want more structure, you can also try GraphQL.
I’d make so many syntax errors without at least some sort of lint/build step.
I write and iterate my blog posts in a raw text file. When I’m happy I make a copy/paste an existing post and then modify the title and body.
There’s no server or build step. I just open the local .html file in my local browser. My build process is change HTML and press F5 in browser.
I have experimented with markdown-to-html converters. They’re ok but not a game changer.
Most of my posts have no JavaScript. But a few with custom visualizations do.
The goal was to eliminate redundant computation, and it did that, but there are much better approaches these days. What I ended up with was just bespoke, persistent caching.
> There have now been a significant number of attempts to "platformitize" dynamic computation — "serverless" programming like AWS Lambda, WASM runtimes like those provided by CloudFlare and Fastly, full container deployment via Fly.io and cloud providers. None of these have an API nearly as stable as the filesystem API used to host static files, but it's a matter of time before APIs end up well-established.
Containers and WASM are certainly interesting vectors of standardization, but even if everything goes fully to plan by the most bullish proponents, you still have a much more complex environment where incentives to break backwards compatibility make it exceedingly unlikely that you'll be able to just grab a container and WASM binary and drop them into any commodity host 30 years from now. Of course HTML/CSS rendering could break too, but incentives are skewed more in favor backwards compatibility. Also, because it's just a simple, human-readable file format, slight breakage doesn't render the archive useless. Heck, even the destruction of the internet and all servers doesn't render the file useless—you just need to be able to decode ASCII/UTF-8 to extract value.
I think a better thesis for the original author would have been that static site generators are not necessarily simpler than dynamic sites generated at request time. I agree with that wholeheartedly, but the beauty of the SSG is that if at any time I want to stop maintaining the code, I have a ready-made servable version of the site that is trivially archivable in perpetuity. Standardized data formats expressed in simple files will always be more durable than code.
I wrote my blog's static site generator 10 years ago and I'm still using it. If I want something it doesn't do, I change it. It's still a single-file perl script and it's easier (for me) than any other option.
People used to do this in the 90s and early 2000s, but it turned out to be a hilariously bad idea security-wise. Even the enthusiasts these days use a dedicated server somewhere in a datacenter. Services like Github Pages and Cloudflare exist for a reason, and it isn't because anyone is trying to gatekeep web hosting.
I love having a completely independent working local copy. My environment is perfect for my needs or I change it.
Basically my deployment plans and disaster recovery are indistinguishable.
There is no custom executable to run, there is no need for authentication, there is no need to write files to disk, there is no need to parse user-provided content, there is no need to access a database, there are no custom libraries to update... A static website can literally be "upload and forget", and that simply isn't the case for dynamic sites.
You get everything anyway, and nothing you do is used by the server.
Of course the server itself can be attacked, though it is much more difficult then with dynamic sites.