<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Deepanshu Gautam · Notes on building things</title>
  <link href="https://www.deepanshugautam.com/notes"/>
  <link rel="self" href="https://www.deepanshugautam.com/notes/feed.xml"/>
  <id>https://www.deepanshugautam.com/notes/feed.xml</id>
  <updated>2026-11-07T00:00:00+09:00</updated>
  <author><name>Deepanshu Gautam</name></author>
  <entry>
    <title>Rebuilding my website as a product</title>
    <link href="https://www.deepanshugautam.com/notes/rebuilding-my-website"/>
    <id>https://www.deepanshugautam.com/notes/rebuilding-my-website</id>
    <published>2026-11-07T00:00:00+09:00</published>
    <updated>2026-11-07T00:00:00+09:00</updated>
    <summary>Why I moved deepanshugautam.com off a site builder and gave it a design system, two languages and a deploy gate.</summary>
    <content type="html">&lt;p&gt;For years this site was a page on a site builder: a short bio, one app, and a privacy policy that Apple&amp;#39;s App Store links to. It worked, but it wasn&amp;#39;t &lt;em&gt;mine&lt;/em&gt;. I couldn&amp;#39;t test it, version it or make it fast, and every change was a click in someone else&amp;#39;s editor.&lt;/p&gt;
&lt;p&gt;So I rebuilt it the way I&amp;#39;d build a product.&lt;/p&gt;
&lt;h2&gt;A design system first&lt;/h2&gt;
&lt;p&gt;The site starts with tokens, not pages: a palette (saffron for India, vermilion for Japan, washi paper by day and sumi ink by night), type and spacing scales, and a handful of components. Features only use &lt;em&gt;roles&lt;/em&gt; such as &lt;code&gt;--color-text&lt;/code&gt; or &lt;code&gt;--color-japan-text&lt;/code&gt;, never raw colours, and a check fails the build if one sneaks in. Light and dark mode come for free.&lt;/p&gt;
&lt;h2&gt;Pages rendered at build time, in two languages&lt;/h2&gt;
&lt;p&gt;Every page is rendered to plain HTML when the site is built, once per language: English at &lt;code&gt;/&lt;/code&gt; and Japanese at &lt;code&gt;/ja&lt;/code&gt;. All text lives in one YAML file per language, and the renderer escapes everything by default, so a translation can never inject markup. Search engines get real HTML with &lt;code&gt;hreflang&lt;/code&gt; links, and visitors get a page that works before any JavaScript runs.&lt;/p&gt;
&lt;h2&gt;Addresses are promises&lt;/h2&gt;
&lt;p&gt;The old site had a few URLs other people depend on, like the Budget Buddy privacy policies linked from the App Store. They keep exactly the same addresses, and a unit test fails if one ever stops existing.&lt;/p&gt;
&lt;h2&gt;A gate in front of production&lt;/h2&gt;
&lt;p&gt;Before anything is published, the same fast checks run on my machine and on Cloudflare: linting, type checks, unit tests, and content checks (missing translations, broken links, stale icons and social cards). Browser tests in Chromium and iPhone WebKit check every page, including accessibility in light and dark mode. If anything fails, nothing ships and the last good version stays live.&lt;/p&gt;
&lt;p&gt;It&amp;#39;s more machinery than a personal site strictly needs. But it&amp;#39;s also the kind of machinery I like building, and now the site is something I can keep improving without fear. &lt;strong&gt;You don&amp;#39;t need to be perfect to start&lt;/strong&gt;, but it helps to have tests when you continue.&lt;/p&gt;
</content>
  </entry>
</feed>
