<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jamin</title>
    <description>The latest articles on DEV Community by Jamin (@jamin_e16996ba0e309177).</description>
    <link>https://dev.to/jamin_e16996ba0e309177</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4045948%2F267cb700-e656-41b2-a9e2-02e6f7abe58a.png</url>
      <title>DEV Community: Jamin</title>
      <link>https://dev.to/jamin_e16996ba0e309177</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jamin_e16996ba0e309177"/>
    <language>en</language>
    <item>
      <title>How I Built a Peptide Dosage Calculator with Next.js — and Why SSR Matters More Than You Think</title>
      <dc:creator>Jamin</dc:creator>
      <pubDate>Sun, 26 Jul 2026 02:47:42 +0000</pubDate>
      <link>https://dev.to/jamin_e16996ba0e309177/how-i-built-a-peptide-dosage-calculator-with-nextjs-and-why-ssr-matters-more-than-you-think-3fk8</link>
      <guid>https://dev.to/jamin_e16996ba0e309177/how-i-built-a-peptide-dosage-calculator-with-nextjs-and-why-ssr-matters-more-than-you-think-3fk8</guid>
      <description>&lt;p&gt;A researcher spends 30 seconds doing peptide math before every injection. I built a tool that does it instantly. Here's the surprising thing I learned: &lt;strong&gt;for a calculator tool, SSR isn't about performance — it's about whether Google even knows your calculator exists.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem I Was Solving
&lt;/h2&gt;

&lt;p&gt;If you're not familiar with peptide research: researchers reconstitute lyophilized (freeze-dried) peptides by adding bacteriostatic water, then draw specific doses into insulin syringes. The math isn't hard — it's just annoying:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I have a 10mg vial, added 2ml of water, I need 250mcg per dose — how many units on a 0.3ml syringe?"&lt;/li&gt;
&lt;li&gt;"I'm running BPC-157 and TB-500 together, different vials, different doses — what are my draw volumes?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most researchers use Excel or a notepad. Some use existing peptide calculators, but they're often buried in affiliate-heavy blogs or wrapped in ads. I wanted something &lt;strong&gt;clean, fast, and free&lt;/strong&gt; — so I built &lt;a href="https://bpc157calculator.com" rel="noopener noreferrer"&gt;bpc157calculator.com&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Didn't Build a SPA
&lt;/h2&gt;

&lt;p&gt;This is the core architectural decision, and it might be counterintuitive.&lt;/p&gt;

&lt;p&gt;A calculator tool looks like the perfect SPA candidate: a few inputs, some math, update the DOM. React state, &lt;code&gt;useEffect&lt;/code&gt;, ship it. &lt;strong&gt;I explicitly chose not to do that.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's why:&lt;/p&gt;

&lt;h3&gt;
  
  
  The SSR realization
&lt;/h3&gt;

&lt;p&gt;When someone searches "BPC-157 dosage calculator," Google doesn't execute JavaScript before ranking the page. A CSR calculator sends Google an empty &lt;code&gt;&amp;lt;div id="root"&amp;gt;&lt;/code&gt; and a JS bundle. The actual calculator UI — the inputs, the labels, the headings that tell Google "this page calculates peptide dosages" — &lt;strong&gt;all of that is invisible to the crawler until JavaScript executes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Google &lt;em&gt;does&lt;/em&gt; render JavaScript now, but:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It adds delay — sometimes hours or days&lt;/li&gt;
&lt;li&gt;It's a second pass, not the primary crawl&lt;/li&gt;
&lt;li&gt;The rendering budget is limited — if your JS bundle is heavy, Google might not fully render it at all&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With Next.js SSR, every page delivers fully rendered HTML on first request. The &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;, the calculator labels, the semantic structure — all present in the raw HTML. &lt;strong&gt;Google doesn't need to run your JavaScript to understand your page.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What this means for a calculator tool specifically
&lt;/h3&gt;

&lt;p&gt;A blog post about peptides can get away with CSR because the article text is in the HTML. But a calculator? The entire value proposition is the interactive widget. If Google can't see it, Google doesn't know what to rank you for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SSR is not a performance optimization here. It's a content delivery mechanism.&lt;/strong&gt; The calculator &lt;em&gt;is&lt;/em&gt; your content, and SSR delivers it to crawlers the same way it delivers it to users.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Choice&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Framework&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Next.js 14 (App Router)&lt;/td&gt;
&lt;td&gt;SSR by default, no config needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hosting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cloudflare Pages&lt;/td&gt;
&lt;td&gt;Edge deployment, free tier, instant cache invalidation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tailwind CSS&lt;/td&gt;
&lt;td&gt;Utility-first, tiny bundle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;URL search params&lt;/td&gt;
&lt;td&gt;Calculator state lives in the URL — shareable, bookmarkable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GA4 + GSC&lt;/td&gt;
&lt;td&gt;Standard. Nothing fancy needed at this stage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No database. No auth. No API routes. &lt;strong&gt;The entire site is static pages + client-side math.&lt;/strong&gt; The SSR handles the initial HTML; the calculation logic runs in the browser after hydration. Best of both worlds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture: One Domain, Three Search Intents
&lt;/h2&gt;

&lt;p&gt;The site has threecore pages, each targeting a different search intent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://bpc157calculator.com" rel="noopener noreferrer"&gt;bpc157calculator.com&lt;/a&gt; — "bpc157 calculator" (brand + generic dosage)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://bpc157calculator.com/reconstitution" rel="noopener noreferrer"&gt;bpc157calculator.com/reconstitution&lt;/a&gt; — "peptide reconstitution calculator"&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://bpc157calculator.com/blend" rel="noopener noreferrer"&gt;bpc157calculator.com/blend&lt;/a&gt; — "bpc-157 tb-500 blend dosage calculator"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Semaglutide and other peptides (15+ total) are handled on the homepage via a dropdown selector — no separate routes. This was a deliberate choice: I wanted separate pages only when the search intent was fundamentally different. "Dosage," "reconstitution," and "blend dosing" are three distinct intents. "Semaglutide dosage" vs "BPC-157 dosage" is the same intent with a different parameter — that's what a dropdown is for.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why separate pages instead of one SPA with tabs?
&lt;/h3&gt;

&lt;p&gt;Because Google ranks &lt;strong&gt;pages&lt;/strong&gt;, not apps.&lt;/p&gt;

&lt;p&gt;A single-page app with tabs for "Dosage," "Reconstitution," and "Blend" means one URL competing for three very different search intents. Your &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; can only be one thing. Your &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; can only be one thing. Google will rank you for &lt;strong&gt;one&lt;/strong&gt; of those intents and ignore the others.&lt;/p&gt;

&lt;p&gt;Separate pages let each route have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Its own &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; matching the exact search query&lt;/li&gt;
&lt;li&gt;Its own &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; reinforcing the topic&lt;/li&gt;
&lt;li&gt;Its own meta description&lt;/li&gt;
&lt;li&gt;Internal links between them passing relevance signals both ways&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Internal linking structure
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://bpc157calculator.com/" rel="noopener noreferrer"&gt;Homepage&lt;/a&gt;&lt;br&gt;
├── Links to &lt;a href="https://bpc157calculator.com/reconstitution" rel="noopener noreferrer"&gt;Reconstitution Calculator&lt;/a&gt;&lt;br&gt;
│     ("Need to reconstitute first? Use our reconstitution calculator")&lt;br&gt;
├── Links to &lt;a href="https://bpc157calculator.com/blend" rel="noopener noreferrer"&gt;Blend Calculator&lt;/a&gt;&lt;br&gt;
│     ("Running a stack? Try the blend calculator")&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bpc157calculator.com/reconstitution" rel="noopener noreferrer"&gt;bpc157calculator.com/reconstitution&lt;/a&gt;&lt;br&gt;
├── Links back to &lt;a href="https://bpc157calculator.com" rel="noopener noreferrer"&gt;Homepage&lt;/a&gt;&lt;br&gt;
│     ("Calculated your volume? Now calculate your dose")&lt;br&gt;
└── Links to &lt;a href="https://bpc157calculator.com/blend" rel="noopener noreferrer"&gt;Blend Calculator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bpc157calculator.com/blend" rel="noopener noreferrer"&gt;bpc157calculator.com/blend&lt;/a&gt;&lt;br&gt;
├── Links back to &lt;a href="https://bpc157calculator.com" rel="noopener noreferrer"&gt;Homepage&lt;/a&gt;&lt;br&gt;
└── Links to &lt;a href="https://bpc157calculator.com/reconstitution" rel="noopener noreferrer"&gt;Reconstitution Calculator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every page links to at least two others, forming a tight cluster. Google sees this as a coherent topical group, not isolated pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SEO Decisions That Actually Mattered
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Semantic HTML over &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; soup
&lt;/h3&gt;

&lt;p&gt;Every calculator page uses &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;fieldset&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;legend&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; — not just for accessibility, but because these elements tell Google about the structure of your page. A &lt;code&gt;&amp;lt;fieldset&amp;gt;&lt;/code&gt; with a &lt;code&gt;&amp;lt;legend&amp;gt;&lt;/code&gt; that says "Peptide Dosage Calculator" is a much stronger signal than a &lt;code&gt;&amp;lt;div class="calculator-wrapper"&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Title tags that mirror search queries
&lt;/h3&gt;

&lt;p&gt;I didn't get clever with branding. The homepage title is exactly what people search:&lt;br&gt;
BPC-157 Dosage Calculator — Free Peptide Reconstitution Tool&lt;/p&gt;

&lt;p&gt;Not "BPC157Calculator — The Best Peptide Tool for Researchers." Nobody searches that.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. URL search params for shareable state
&lt;/h3&gt;

&lt;p&gt;Calculator state (peptide selected, vial size, water volume, dose) lives in URL search params. This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users can share exact calculations via URL&lt;/li&gt;
&lt;li&gt;Every state variant is technically a unique URL (though I canonicalize to the base route)&lt;/li&gt;
&lt;li&gt;Someone sharing &lt;code&gt;bpc157calculator.com?peptide=tb500&amp;amp;vial=5mg&lt;/code&gt; on a forum is creating a de facto backlink with context&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. What I &lt;em&gt;didn't&lt;/em&gt; obsess over
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Web Vitals at launch:&lt;/strong&gt; Yes, performance matters. But a 95 vs 98 Lighthouse score won't make or break a new site. Ship first, optimize later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema markup for calculators:&lt;/strong&gt; I added basic &lt;code&gt;WebApplication&lt;/code&gt; schema, but it's unclear how much Google actually uses calculator-specific schema. Not worth spending days on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blog/content section:&lt;/strong&gt; I deliberately didn't add one. A calculator tool doesn't need a blog to rank for calculator keywords. Adding thin content pages right now would dilute topical focus. I'll add educational content later, once the core pages are ranking.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Results So Far (Honest Version)
&lt;/h2&gt;

&lt;p&gt;The site has been live for a few days. Here's the unvarnished data from Google Search Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;8 pages indexed&lt;/strong&gt; — which is expected. Next.js SSR + a clean sitemap.xml + no JS required for content = Google indexes you fast. This is not impressive; it's just what happens when you don't make Google work hard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;~15-20 impressions/day across ~10 query variations&lt;/strong&gt; — all variations of "bpc-157 dosage calculator," "peptide reconstitution calculator," etc. Positions ranging from 40-90 (pages 5-9). Zero clicks, which at those positions is mathematically expected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queries are dead-on relevant&lt;/strong&gt; — Google is showing my pages for &lt;em&gt;exactly&lt;/em&gt; the terms I targeted. No random "dog food" queries. The intent matching is working.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest takeaway: &lt;strong&gt;Getting indexed fast is easy if you use SSR. Getting ranked is the hard part, and it takes time and backlinks.&lt;/strong&gt; I'm in the "Google is testing my pages at position 60-80" phase right now. Here's what I'm doing to move up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Building backlink signals&lt;/strong&gt; — submitting to developer directories (Dev.to, Alternatives.to), sharing on Twitter/LinkedIn, engaging in peptide research communities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not touching the pages&lt;/strong&gt; — every title/content change resets Google's evaluation. I'm keeping everything frozen for at least 2-3 weeks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring, not obsessing&lt;/strong&gt; — checking GSC every 3 days, not every 3 hours&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pre-launch backlink groundwork.&lt;/strong&gt; I shipped the site, &lt;em&gt;then&lt;/em&gt; started thinking about backlinks. If I'd spent the week before launch preparing guest posts, directory submissions, and community introductions, the backlink signals would have arrived in Google's first crawl, not days later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;More unique copy on calculator pages.&lt;/strong&gt; The &lt;code&gt;/reconstitution&lt;/code&gt;, &lt;code&gt;/blend&lt;/code&gt;, and &lt;code&gt;/semaglutide&lt;/code&gt; pages share some boilerplate. Google might see them as thin or partially duplicate. Each page should have 200-300 words of unique introductory text explaining the specific use case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consider an EMD alternative.&lt;/strong&gt; BPC157Calculator.com is an exact-match domain for the BPC-157 niche, but it might limit how Google treats my Semaglutide and other peptide pages. A broader name like "PeptideCalc" or "ResearchCalc" would have been more flexible. Tradeoff: EMD gives a ranking boost for the exact phrase; broader name gives room to expand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GA4 setup before launch.&lt;/strong&gt; I set up GA4 after the site was already live, missing the first few hours of data. Not critical, but annoying.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Key Takeaways for Other Indie Builders
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SSR is not just for blogs and e-commerce.&lt;/strong&gt; Calculator tools, generators, converters — anything where the UI &lt;em&gt;is&lt;/em&gt; the content — benefit enormously from server-rendered HTML.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Separate pages for separate intents.&lt;/strong&gt; One SPA = one ranking opportunity. Multiple SSR pages = multiple ranking opportunities. The overhead of maintaining a few extra route files is trivial compared to the SEO upside.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ship, then wait.&lt;/strong&gt; The hardest part after launching a new site is resisting the urge to tweak everything based on 48 hours of GSC data. Google needs weeks, not days, to evaluate a new domain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The boring stuff works.&lt;/strong&gt; Semantic HTML, matching title tags to search queries, clean internal linking — none of it is exciting, but collectively it's what moves the needle more than any "SEO hack."&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;em&gt;You can try the calculator at &lt;a href="https://bpc157calculator.com" rel="noopener noreferrer"&gt;bpc157calculator.com&lt;/a&gt;. If you're working on something similar or have feedback on the architecture, I'd love to hear it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
