{"id":905,"date":"2026-10-15T15:56:38","date_gmt":"2026-10-15T13:56:38","guid":{"rendered":"https:\/\/chauquest.com\/?p=905"},"modified":"2026-10-18T23:52:53","modified_gmt":"2026-10-18T21:52:53","slug":"astro-keystatic-cloudflare-freelance-website","status":"publish","type":"post","link":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/","title":{"rendered":"How I built my freelance website : Astro, Keystatic and Cloudflare"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Why would I build my freelance website without WordPress, when this blog has been running on it since 2023 ?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since 2026 I am freelancing in Japan, in the Sendai area : websites, data and AI tools, and video. The first thing a client asks is &#8220;can I see what you did ?&#8221;. Until now the answer was this blog, which is nice for makers but not really what a company wants to read before asking for a quote. So in July I built <a href=\"https:\/\/eymeric.me\">eymeric.me<\/a>, my freelance portfolio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this article I will explain how the site is built (Astro, Keystatic and Cloudflare Workers), why I chose each brick, and what I would reuse for a client. Everything here works for any small multilingual site.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quick numbers before we start :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First commit on 5 July 2026, first full version the same day<\/li>\n\n<li>99 commits until the end of September<\/li>\n\n<li>About 40 static pages, in English, French and Japanese<\/li>\n\n<li>Running cost : almost zero, static files on Cloudflare are free so I only pay the domain<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Features I wanted<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Three languages : English, French and Japanese, because my clients are in Japan and in France<\/li>\n\n<li>Two faces : an engineering side (SaaS, websites, electronics, infrastructure) and a creative side (videos, photos, making)<\/li>\n\n<li>Fast, with no server to maintain<\/li>\n\n<li>Editable without code, through a CMS<\/li>\n\n<li>Easy to find on Google from day one<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Two sides, one pamphlet<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The site has two sides, Engineering and Creative, and a tab on the edge of the screen swipes from one to the other. I didn&#8217;t want two separate websites, because in my point of view it is the same work : engineering is what I build, and the creative side is how I tell it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The layout is like an open pamphlet : creative is the left leaf, engineering the right one, and the whole page is mirrored with only two CSS variables (<code>--side-align<\/code> and <code>--side-dir<\/code>). Each side has its own ink, Prussian blue for engineering and vermilion for creative, on a washi paper background. Headings use the Fraunces font, straight on engineering and italic on creative.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"640\" src=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-creative-side-1024x640.jpg\" alt=\"Creative side of eymeric.me, the same layout mirrored with italic headings\" class=\"wp-image-910\" srcset=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-creative-side-1024x640.jpg 1024w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-creative-side-300x188.jpg 300w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-creative-side-768x480.jpg 768w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-creative-side.jpg 1440w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The creative side : the same page mirrored, vermilion instead of blue, italic headings, and the Engineering tab now on the right edge.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">My first version computed the creative colour from the blue, taking the opposite on the colour wheel. It was mathematically perfect and it looked&#8230; generated. So I picked both inks by hand and checked their contrast for accessibility (WCAG AA), in light and dark mode.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The stack<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before the details, here is the whole picture :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"320\" src=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-architecture-1024x320.png\" alt=\"Diagram : Keystatic on the laptop writes files to Git, git push, Cloudflare builds static HTML served to the browser\" class=\"wp-image-911\" srcset=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-architecture-1024x320.png 1024w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-architecture-300x94.png 300w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-architecture-768x240.png 768w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-architecture-1536x480.png 1536w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-architecture.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The whole workflow : the CMS stays on my laptop, Cloudflare only gets static files.<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Astro, fully static<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The site is built with <a href=\"https:\/\/astro.build\">Astro<\/a> in <code>output: 'static'<\/code> mode : the build gives a folder of HTML files and nothing runs on a server. There is only one piece of React on the whole site, the toggle between the two sides. Everything else is plain HTML and CSS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pros :<\/strong> fast, nothing to update or secure, any static host works<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Cons :<\/strong> every change needs a rebuild and a deploy<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Keystatic on Cloudflare Workers : run the CMS only in dev<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is the magic sauce of the project ! <a href=\"https:\/\/keystatic.com\">Keystatic<\/a> is a CMS that writes Markdown and JSON files directly into the Git repository. I open <code>\/keystatic<\/code> locally, edit a project, commit, push, and Cloudflare rebuilds the site.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"640\" src=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/keystatic-admin-co2-monitor-1024x640.jpg\" alt=\"Keystatic admin running locally, editing the CO2 monitor project of eymeric.me\" class=\"wp-image-912\" srcset=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/keystatic-admin-co2-monitor-1024x640.jpg 1024w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/keystatic-admin-co2-monitor-300x188.jpg 300w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/keystatic-admin-co2-monitor-768x480.jpg 768w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/keystatic-admin-co2-monitor.jpg 1440w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Keystatic running on my laptop, editing the CO2 monitor project. Saving writes an MDX file in the repository, nothing else.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">At first I wanted the CMS online, with GitHub storage and a server adapter on Cloudflare. It doesn&#8217;t work : Keystatic&#8217;s admin expects a Node runtime, and a Cloudflare Worker only emulates part of Node through the <code>nodejs_compat<\/code> flag. And even if it worked, I needed a GitHub App and three secrets just to log in to an admin page that only I use. So I flipped the problem. The CMS is loaded only when I run <code>astro dev<\/code>, and the production build ships no CMS at all. It&#8217;s a tiny Astro integration :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ astro.config.mjs (simplified)\nfunction keystaticDevOnly() {\n  const ks = keystatic();\n  return {\n    name: 'keystatic-dev-only',\n    hooks: {\n      'astro:config:setup': (params) =&gt; {\n        if (params.command !== 'dev') return; \/\/ production build : no CMS at all\n        return ks.hooks['astro:config:setup']?.(params);\n      },\n    },\n  };\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pros :<\/strong> there is no admin page in production, so nothing to hack and nothing to patch<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Cons :<\/strong> I can only edit from a computer with the repository and Node installed. For a portfolio that only I edit, it&#8217;s totally fine. For a client who wants to edit from their phone, it&#8217;s not.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cloudflare for hosting<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>dist\/<\/code> folder is served by Cloudflare as static assets. The whole Wrangler config fits in a few lines :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"name\": \"freelance-landing-page\",\n  \"compatibility_date\": \"2026-07-13\",\n  \"assets\": { \"directory\": \".\/dist\" } \/\/ the only thing Cloudflare needs to know\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redirects (for example <code>\/<\/code> to <code>\/en\/engineering\/<\/code>) are plain 301 in a <code>_redirects<\/code> file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Design tokens, checked by grep<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">All colours are tokens in three CSS files : primitive, then semantic, then one theme per side. Components are not allowed to use a colour value directly, and I check it with a single grep in <code>package.json<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm run tokens:check\n# runs : grep -rIE '#[0-9a-fA-F]{3,6}|rgb\\(|hsl\\(' src\/components src\/layouts src\/pages<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s really simple, but thanks to it a palette change only means editing the token files.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Three languages<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Each project exists three times, in <code>content\/projects\/en\/<\/code>, <code>fr\/<\/code> and <code>ja\/<\/code>, with the same file name. Thanks to that, the language switcher always finds the twin page, and so does Google.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"473\" height=\"1024\" src=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-japanese-mobile-473x1024.jpg\" alt=\"Japanese version of eymeric.me on a phone\" class=\"wp-image-913\" style=\"width:360px\" srcset=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-japanese-mobile-473x1024.jpg 473w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-japanese-mobile-139x300.jpg 139w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-japanese-mobile-768x1662.jpg 768w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-japanese-mobile-710x1536.jpg 710w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-japanese-mobile.jpg 780w\" sizes=\"auto, (max-width: 473px) 100vw, 473px\" \/><figcaption class=\"wp-element-caption\">The Japanese version on a phone : same page, same file name, different folder.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Visitors land on the English version and pick their language in the header. The site never redirects you based on your browser language, which is also what Google recommends for multilingual sites.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How Google understands the site<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For a portfolio, SEO is mainly two questions : does Google know that the three versions of a page are the same page, and does it know who is behind the site ?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the languages, every page declares its own address and its twins in the other languages (the hreflang tags, plus <code>x-default<\/code> for the English fallback). The sitemap repeats the same links. So Google sees one page in three languages, not three copies of the same content.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the person behind it, each page carries structured data (JSON-LD). It&#8217;s a small block of code that visitors never see, and it tells Google &#8220;this is a person, an engineer in Sendai, here are the services and here are the projects&#8221;. It&#8217;s the same information as on the page, just written for machines.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The sitemap also gives the date of the last real edit of each page, taken from Git. So when I update an old project, Google knows it changed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And the most basic lesson : write the words your clients search. My first version never said &#8220;freelance&#8221; anywhere, on a freelance website ^^ Now it&#8217;s the first word of the page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Built with an AI pair programmer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Full disclosure : most of the 99 commits were written with Claude Code. In my point of view it is still a tool rather than a game changer. It types fast, but the architecture, the review of every change and catching the mistakes were still my job.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Result<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Today <a href=\"https:\/\/eymeric.me\">eymeric.me<\/a> has 7 engineering projects (the newest one is <a href=\"https:\/\/eymeric.me\/en\/engineering\/recherche-maison\/\">recherche-maison<\/a>), 1 creative project and 3 services, in three languages. Some of the projects come from this blog : the <a href=\"https:\/\/chauquest.com\/index.php\/engineering\/diy-co2-monitor-guide\/\">CO2 monitor<\/a>, the <a href=\"https:\/\/chauquest.com\/index.php\/engineering\/diy-taiko-no-tatsujin-arcade-controller-complete-tutorial\/\">Taiko controller<\/a> and the Formula Student <a href=\"https:\/\/chauquest.com\/index.php\/engineering\/formula-student\/in-depth-review-of-the-tsal-design-and-explanation\/\">TSAL<\/a> now have their own page there, written for clients instead of makers.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"640\" src=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-co2-monitor-project-1024x640.jpg\" alt=\"CO2 monitor project page on eymeric.me\" class=\"wp-image-914\" srcset=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-co2-monitor-project-1024x640.jpg 1024w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-co2-monitor-project-300x188.jpg 300w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-co2-monitor-project-768x480.jpg 768w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-co2-monitor-project.jpg 1440w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The CO2 monitor from this blog, rewritten as a project page for clients.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">One last detail I like : my quotes and invoices are signed PDFs, and <a href=\"https:\/\/eymeric.me\/gpg\/\">eymeric.me\/gpg<\/a> hosts the public key, so a client can check that a document really comes from me.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lighthouse scores<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">I ran Lighthouse (version 13.5) on the home page and on a project page, three times each on mobile and on desktop. Here are the medians :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"198\" src=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-lighthouse-mobile-1024x198.png\" alt=\"Lighthouse scores of the eymeric.me home page on mobile : Performance 79, Accessibility 100, Best Practices 81, SEO 100\" class=\"wp-image-916\" srcset=\"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-lighthouse-mobile-1024x198.png 1024w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-lighthouse-mobile-300x58.png 300w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-lighthouse-mobile-768x149.png 768w, https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-lighthouse-mobile.png 1220w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Lighthouse on the home page, mobile, the median of three runs.<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Page<\/th><th>Device<\/th><th>Performance<\/th><th>Accessibility<\/th><th>Best practices<\/th><th>SEO<\/th><\/tr><\/thead><tbody><tr><td>Home<\/td><td>Mobile<\/td><td>79<\/td><td>100<\/td><td>81<\/td><td>100<\/td><\/tr><tr><td>Home<\/td><td>Desktop<\/td><td>97<\/td><td>100<\/td><td>81<\/td><td>100<\/td><\/tr><tr><td>CO2 monitor project<\/td><td>Mobile<\/td><td>90<\/td><td>100<\/td><td>81<\/td><td>100<\/td><\/tr><tr><td>CO2 monitor project<\/td><td>Desktop<\/td><td>100<\/td><td>100<\/td><td>81<\/td><td>100<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Accessibility and SEO are at 100 everywhere, which was the goal. The weak point is performance on mobile. Lighthouse simulates a slow 4G phone, and on it the home page needs 5.1 s before its big headline is fully drawn. The clearest problem is the images : they are sent at their full desktop size, so about 550 KB of the 800 KB home page are photos, and Lighthouse estimates that 500 KB could be saved on a phone. Serving smaller images to phones is the next fix on my list.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Best practices is stuck at 81 on every page because of one script, the bot detection that Cloudflare adds to the page by itself. And there is no analytics and no third-party request at all.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s it for this tour ! If you need a fast multilingual website, a SaaS or some electronics, <a href=\"https:\/\/eymeric.me\/en\/engineering\/\">my freelance portfolio<\/a> is the place to contact me.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And yes, I see the irony of writing all this on a WordPress blog. Maybe this blog will be the next one to move&#8230; stay tuned ! <a href=\"https:\/\/chauquest.com\/index.php\/engineering\/it-development\/french-dpe-database-in-the-browser-duckdb-wasm\/\">The next article<\/a> is about my current side project, <a href=\"https:\/\/recherche-maison.com\">recherche-maison.com<\/a> : the whole French energy certificate database, queried directly in your browser.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How I built eymeric.me, my trilingual freelance portfolio : static Astro, a CMS that only runs on my laptop, Cloudflare static hosting, and multilingual SEO.<\/p>\n","protected":false},"author":1,"featured_media":909,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"footnotes":""},"categories":[1,49],"tags":[59,61,60],"class_list":["post-905","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-article","category-it-development","tag-astro","tag-cloudflare","tag-keystatic"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"Keystatic&#039;s admin can&#039;t run on Cloudflare Workers, so I only load it in astro dev. How I built my trilingual Astro portfolio, code included.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Chauchat Eymeric\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Eymeric Chauchat - my Engineering blog\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Keystatic on Cloudflare Workers : local-only CMS with Astro\" \/>\n\t\t<meta property=\"og:description\" content=\"Keystatic&#039;s admin can&#039;t run on Cloudflare Workers, so I only load it in astro dev. How I built my trilingual Astro portfolio, code included.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-10-15T13:56:38+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-10-18T21:52:53+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Keystatic on Cloudflare Workers : local-only CMS with Astro\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Keystatic&#039;s admin can&#039;t run on Cloudflare Workers, so I only load it in astro dev. How I built my trilingual Astro portfolio, code included.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#blogposting\",\"name\":\"Keystatic on Cloudflare Workers : local-only CMS with Astro\",\"headline\":\"How I built my freelance website : Astro, Keystatic and Cloudflare\",\"author\":{\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/author\\\/chauquest-com\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/chauquest.com\\\/#person\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/chauquest.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/eymeric-me-engineering-side.jpg\",\"width\":1440,\"height\":900,\"caption\":\"The engineering side of eymeric.me : Prussian blue, straight headings, and the Creative tab on the left edge.\"},\"datePublished\":\"2026-10-15T15:56:38+02:00\",\"dateModified\":\"2026-10-18T23:52:53+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":1,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#webpage\"},\"articleSection\":\"Article, IT &amp; Development, Astro, Cloudflare, Keystatic\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/chauquest.com\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/category\\\/engineering\\\/#listItem\",\"name\":\"Engineering\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/category\\\/engineering\\\/#listItem\",\"position\":2,\"name\":\"Engineering\",\"item\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/category\\\/engineering\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/category\\\/engineering\\\/it-development\\\/#listItem\",\"name\":\"IT &amp; Development\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/category\\\/engineering\\\/it-development\\\/#listItem\",\"position\":3,\"name\":\"IT &amp; Development\",\"item\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/category\\\/engineering\\\/it-development\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#listItem\",\"name\":\"How I built my freelance website : Astro, Keystatic and Cloudflare\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/category\\\/engineering\\\/#listItem\",\"name\":\"Engineering\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#listItem\",\"position\":4,\"name\":\"How I built my freelance website : Astro, Keystatic and Cloudflare\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/category\\\/engineering\\\/it-development\\\/#listItem\",\"name\":\"IT &amp; Development\"}}]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/#person\",\"name\":\"Chauchat Eymeric\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#personImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/733daea7054c24e570a41a59b2a06d4b4c62fa3d15233b6543f4f65698b9c0f2?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Chauchat Eymeric\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/author\\\/chauquest-com\\\/#author\",\"url\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/author\\\/chauquest-com\\\/\",\"name\":\"Chauchat Eymeric\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/733daea7054c24e570a41a59b2a06d4b4c62fa3d15233b6543f4f65698b9c0f2?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Chauchat Eymeric\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#webpage\",\"url\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/\",\"name\":\"Keystatic on Cloudflare Workers : local-only CMS with Astro\",\"description\":\"Keystatic's admin can't run on Cloudflare Workers, so I only load it in astro dev. How I built my trilingual Astro portfolio, code included.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/chauquest.com\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/author\\\/chauquest-com\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/author\\\/chauquest-com\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/chauquest.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/eymeric-me-engineering-side.jpg\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#mainImage\",\"width\":1440,\"height\":900,\"caption\":\"The engineering side of eymeric.me : Prussian blue, straight headings, and the Creative tab on the left edge.\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/chauquest.com\\\/index.php\\\/article\\\/astro-keystatic-cloudflare-freelance-website\\\/#mainImage\"},\"datePublished\":\"2026-10-15T15:56:38+02:00\",\"dateModified\":\"2026-10-18T23:52:53+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/chauquest.com\\\/#website\",\"url\":\"https:\\\/\\\/chauquest.com\\\/\",\"name\":\"chauquest.com\",\"description\":\"my Engineering blog\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/chauquest.com\\\/#person\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Keystatic on Cloudflare Workers : local-only CMS with Astro","description":"Keystatic's admin can't run on Cloudflare Workers, so I only load it in astro dev. How I built my trilingual Astro portfolio, code included.","canonical_url":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#blogposting","name":"Keystatic on Cloudflare Workers : local-only CMS with Astro","headline":"How I built my freelance website : Astro, Keystatic and Cloudflare","author":{"@id":"https:\/\/chauquest.com\/index.php\/author\/chauquest-com\/#author"},"publisher":{"@id":"https:\/\/chauquest.com\/#person"},"image":{"@type":"ImageObject","url":"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-engineering-side.jpg","width":1440,"height":900,"caption":"The engineering side of eymeric.me : Prussian blue, straight headings, and the Creative tab on the left edge."},"datePublished":"2026-10-15T15:56:38+02:00","dateModified":"2026-10-18T23:52:53+02:00","inLanguage":"en-US","commentCount":1,"mainEntityOfPage":{"@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#webpage"},"isPartOf":{"@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#webpage"},"articleSection":"Article, IT &amp; Development, Astro, Cloudflare, Keystatic"},{"@type":"BreadcrumbList","@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/chauquest.com\/#listItem","position":1,"name":"Home","item":"https:\/\/chauquest.com\/","nextItem":{"@type":"ListItem","@id":"https:\/\/chauquest.com\/index.php\/category\/engineering\/#listItem","name":"Engineering"}},{"@type":"ListItem","@id":"https:\/\/chauquest.com\/index.php\/category\/engineering\/#listItem","position":2,"name":"Engineering","item":"https:\/\/chauquest.com\/index.php\/category\/engineering\/","nextItem":{"@type":"ListItem","@id":"https:\/\/chauquest.com\/index.php\/category\/engineering\/it-development\/#listItem","name":"IT &amp; Development"},"previousItem":{"@type":"ListItem","@id":"https:\/\/chauquest.com\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/chauquest.com\/index.php\/category\/engineering\/it-development\/#listItem","position":3,"name":"IT &amp; Development","item":"https:\/\/chauquest.com\/index.php\/category\/engineering\/it-development\/","nextItem":{"@type":"ListItem","@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#listItem","name":"How I built my freelance website : Astro, Keystatic and Cloudflare"},"previousItem":{"@type":"ListItem","@id":"https:\/\/chauquest.com\/index.php\/category\/engineering\/#listItem","name":"Engineering"}},{"@type":"ListItem","@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#listItem","position":4,"name":"How I built my freelance website : Astro, Keystatic and Cloudflare","previousItem":{"@type":"ListItem","@id":"https:\/\/chauquest.com\/index.php\/category\/engineering\/it-development\/#listItem","name":"IT &amp; Development"}}]},{"@type":"Person","@id":"https:\/\/chauquest.com\/#person","name":"Chauchat Eymeric","image":{"@type":"ImageObject","@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#personImage","url":"https:\/\/secure.gravatar.com\/avatar\/733daea7054c24e570a41a59b2a06d4b4c62fa3d15233b6543f4f65698b9c0f2?s=96&d=mm&r=g","width":96,"height":96,"caption":"Chauchat Eymeric"}},{"@type":"Person","@id":"https:\/\/chauquest.com\/index.php\/author\/chauquest-com\/#author","url":"https:\/\/chauquest.com\/index.php\/author\/chauquest-com\/","name":"Chauchat Eymeric","image":{"@type":"ImageObject","@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/733daea7054c24e570a41a59b2a06d4b4c62fa3d15233b6543f4f65698b9c0f2?s=96&d=mm&r=g","width":96,"height":96,"caption":"Chauchat Eymeric"}},{"@type":"WebPage","@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#webpage","url":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/","name":"Keystatic on Cloudflare Workers : local-only CMS with Astro","description":"Keystatic's admin can't run on Cloudflare Workers, so I only load it in astro dev. How I built my trilingual Astro portfolio, code included.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/chauquest.com\/#website"},"breadcrumb":{"@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#breadcrumblist"},"author":{"@id":"https:\/\/chauquest.com\/index.php\/author\/chauquest-com\/#author"},"creator":{"@id":"https:\/\/chauquest.com\/index.php\/author\/chauquest-com\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/chauquest.com\/wp-content\/uploads\/2026\/10\/eymeric-me-engineering-side.jpg","@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#mainImage","width":1440,"height":900,"caption":"The engineering side of eymeric.me : Prussian blue, straight headings, and the Creative tab on the left edge."},"primaryImageOfPage":{"@id":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/#mainImage"},"datePublished":"2026-10-15T15:56:38+02:00","dateModified":"2026-10-18T23:52:53+02:00"},{"@type":"WebSite","@id":"https:\/\/chauquest.com\/#website","url":"https:\/\/chauquest.com\/","name":"chauquest.com","description":"my Engineering blog","inLanguage":"en-US","publisher":{"@id":"https:\/\/chauquest.com\/#person"}}]},"og:locale":"en_US","og:site_name":"Eymeric Chauchat - my Engineering blog","og:type":"article","og:title":"Keystatic on Cloudflare Workers : local-only CMS with Astro","og:description":"Keystatic's admin can't run on Cloudflare Workers, so I only load it in astro dev. How I built my trilingual Astro portfolio, code included.","og:url":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/","article:published_time":"2026-10-15T13:56:38+00:00","article:modified_time":"2026-10-18T21:52:53+00:00","twitter:card":"summary_large_image","twitter:title":"Keystatic on Cloudflare Workers : local-only CMS with Astro","twitter:description":"Keystatic's admin can't run on Cloudflare Workers, so I only load it in astro dev. How I built my trilingual Astro portfolio, code included."},"aioseo_meta_data":{"post_id":"905","title":"Keystatic on Cloudflare Workers : local-only CMS with Astro","description":"Keystatic's admin can't run on Cloudflare Workers, so I only load it in astro dev. How I built my trilingual Astro portfolio, code included.","keywords":null,"keyphrases":{"focus":{"keyphrase":"keystatic cloudflare workers","score":0,"analysis":[]},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"BlogPosting","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":0,"frequency":"default","local_seo":null,"limit_modified_date":false,"created":"2026-10-15 12:06:46","updated":"2026-10-18 22:55:02","focus_keyword":"keystatic cloudflare workers","additional_keywords":null,"truseo_locale":null,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"breadcrumb_settings":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/chauquest.com\/\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/chauquest.com\/index.php\/category\/engineering\/\" title=\"Engineering\">Engineering<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/chauquest.com\/index.php\/category\/engineering\/it-development\/\" title=\"IT &amp; Development\">IT &amp; Development<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tHow I built my freelance website : Astro, Keystatic and Cloudflare\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/chauquest.com\/"},{"label":"Engineering","link":"https:\/\/chauquest.com\/index.php\/category\/engineering\/"},{"label":"IT &amp; Development","link":"https:\/\/chauquest.com\/index.php\/category\/engineering\/it-development\/"},{"label":"How I built my freelance website : Astro, Keystatic and Cloudflare","link":"https:\/\/chauquest.com\/index.php\/article\/astro-keystatic-cloudflare-freelance-website\/"}],"_links":{"self":[{"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/posts\/905","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/comments?post=905"}],"version-history":[{"count":4,"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/posts\/905\/revisions"}],"predecessor-version":[{"id":920,"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/posts\/905\/revisions\/920"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/media\/909"}],"wp:attachment":[{"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/media?parent=905"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/categories?post=905"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chauquest.com\/index.php\/wp-json\/wp\/v2\/tags?post=905"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}