---
title: "Subscribe"
description: "Get David V. Kimball's new writing in one email, on the last day of every month."
url: "https://davidvkimball.com/subscribe"
---
# Subscribe

One email, on the last day of every month, with whatever I wrote: AI, tech, productivity, and the occasional opinion you didn't ask for. It's for people who like tinkering with their tools and want the writing without having to check back here. Prefer a feed reader? Follow the [RSS feed](https://davidvkimball.com/rss.xml) instead.

Run a business? [Use It or Skip It](https://lilagents.com/blog/) is probably the one you want: when something new in AI matters for a business like yours, you get what it does and our call on it, use it, wait, or skip it.

<form id="subscribe-form">
  <p>
    <label for="MERGE1">First Name</label><br />
    <input type="text" id="MERGE1" name="MERGE1" required autocomplete="given-name" class="w-full rounded border px-3 py-2" style="background: var(--bg); border-color: var(--input-border); color: var(--text);" />
  </p>
  <p>
    <label for="MERGE2">Last Name</label><br />
    <input type="text" id="MERGE2" name="MERGE2" required autocomplete="family-name" class="w-full rounded border px-3 py-2" style="background: var(--bg); border-color: var(--input-border); color: var(--text);" />
  </p>
  <p>
    <label for="MERGE0">Email</label><br />
    <input type="email" id="MERGE0" name="MERGE0" required autocomplete="email" class="w-full rounded border px-3 py-2" style="background: var(--bg); border-color: var(--input-border); color: var(--text);" />
  </p>
  <p style="position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;" aria-hidden="true">
    <label for="website">Website</label>
    <input type="text" id="website" name="website" tabindex="-1" autocomplete="off" />
  </p>
  <p>
    <button type="submit" class="rounded px-4 py-2 font-medium transition-colors" style="background: var(--text); color: var(--bg);">Subscribe</button>
  </p>
  <p id="subscribe-msg" style="font-size: 0.875rem; min-height: 1.25em;"></p>
</form>

Mailchimp runs the list, and every email has an unsubscribe link. More in the [privacy policy](https://davidvkimball.com/privacy-policy).

<script>
(function() {
  function init() {
    var form = document.getElementById('subscribe-form');
    var msg = document.getElementById('subscribe-msg');
    if (!form || !msg || form.dataset.ready) return;
    form.dataset.ready = 'true';

    // Used server-side to reject submissions faster than a human could fill this in.
    var startedAt = Date.now();

    form.addEventListener('submit', async function(e) {
      e.preventDefault();

      var btn = form.querySelector('button[type="submit"]');
      var data = new FormData(form);
      btn.textContent = 'Subscribing...';
      btn.disabled = true;
      msg.textContent = '';
      msg.style.color = '';

      try {
        var resp = await fetch('/api/subscribe', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            email: data.get('MERGE0'),
            firstName: data.get('MERGE1'),
            lastName: data.get('MERGE2'),
            list: 'blog',
            website: data.get('website') || '',
            elapsed: Date.now() - startedAt,
          }),
        });

        var result = await resp.json();

        if (result.result === 'success') {
          msg.innerHTML = 'Almost there: check your email to confirm. While you wait, <a href="/posts">see what I\'ve been writing</a>.';
          msg.style.color = '#22c55e';
          form.reset();
          if (window.__track) window.__track('subscribe-success:blog');
        } else {
          msg.textContent = result.error || 'Something went wrong. Try again.';
          msg.style.color = '#ef4444';
        }
      } catch (err) {
        msg.textContent = 'Something went wrong. Try again.';
        msg.style.color = '#ef4444';
      }

      btn.textContent = 'Subscribe';
      btn.disabled = false;
    });
  }

  init();
  // This script re-runs on each return to /subscribe, so bind only once.
  if (!window.__subscribeFormBound) {
    window.__subscribeFormBound = true;
    document.addEventListener('astro:page-load', init);
  }
})();
</script>

## Linked mentions

- [The History of My Personal Website](https://davidvkimball.com/posts/the-history-of-my-personal-website)
- [Download Windows 11 Folder Icons](https://davidvkimball.com/posts/download-windows-11-folder-icons)
- [Bullcr*p Marketing Doesn't Work Anymore](https://davidvkimball.com/posts/bullcrap-marketing-doesnt-work-anymore)
- [FAQ](https://davidvkimball.com/faq)
- [Privacy Policy](https://davidvkimball.com/privacy-policy)
