<?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: Viktória Sóti</title>
    <description>The latest articles on DEV Community by Viktória Sóti (@viktria_sti_3fb7d5606cc).</description>
    <link>https://dev.to/viktria_sti_3fb7d5606cc</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%2F4235034%2F70492975-83d3-442d-82bd-caa26ce0abb0.png</url>
      <title>DEV Community: Viktória Sóti</title>
      <link>https://dev.to/viktria_sti_3fb7d5606cc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/viktria_sti_3fb7d5606cc"/>
    <language>en</language>
    <item>
      <title>What I learned building a tattoo aging simulator with Next.js and image AI</title>
      <dc:creator>Viktória Sóti</dc:creator>
      <pubDate>Mon, 09 Nov 2026 12:42:18 +0000</pubDate>
      <link>https://dev.to/viktria_sti_3fb7d5606cc/what-i-learned-building-a-tattoo-aging-simulator-with-nextjs-and-image-ai-15l4</link>
      <guid>https://dev.to/viktria_sti_3fb7d5606cc/what-i-learned-building-a-tattoo-aging-simulator-with-nextjs-and-image-ai-15l4</guid>
      <description>&lt;p&gt;Most people pick a tattoo by looking at a fresh one: crisp lines, saturated colour, perfect skin. But a tattoo spends almost all of its life &lt;em&gt;not&lt;/em&gt; fresh. Ink slowly spreads in the skin, fine lines get wider, small details merge and light colours fade. I wanted a way to see that before booking, on your own body, so I built &lt;a href="https://inkage.app/?lang=en" rel="noopener noreferrer"&gt;InkAge&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You upload a photo of the spot, add a design and set its real size in centimetres. The app draws the tattoo into the photo, then shows it fresh, healed after a year, and after 10, 30 and 50 years. It can also age a tattoo you already have, or preview laser removal after 3, 6 and 10 sessions.&lt;/p&gt;

&lt;p&gt;Here are a few things that turned out to matter more than I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Real size beats pretty pictures
&lt;/h2&gt;

&lt;p&gt;The first versions let you drag a design anywhere at any size. The previews looked great and were useless, because the single biggest factor in how a tattoo ages is how big it is relative to its detail. A 3 cm script tattoo and a 10 cm one age completely differently. Asking for the size in centimetres, and placing the design at that scale on the photo, made the aging previews far more honest.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Explain the result, don't just show it
&lt;/h2&gt;

&lt;p&gt;An image of a blurry 50-year-old tattoo invites one question: &lt;em&gt;why?&lt;/em&gt; So every preview comes with a 0–100 longevity score and the reasons behind it: size, line thickness, colour, placement and sun exposure. The score also offers a sturdier redraw of the same design to compare side by side. People trust a prediction more when they can see what drives it, and they can actually act on it (go bigger, go bolder, pick another spot).&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Two image providers instead of one
&lt;/h2&gt;

&lt;p&gt;The drawing is done by an image model (Google Gemini, with OpenAI as a fallback). Having a second provider wired in from the start saved me more than once: when one returns an error or refuses a perfectly normal photo, the request quietly retries on the other. Users never see the outage.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Language from the browser, crawlers still welcome
&lt;/h2&gt;

&lt;p&gt;The site runs in 35 languages. Every page renders on the server in the language of &lt;code&gt;?lang=xx&lt;/code&gt;. A small Next.js middleware reads &lt;code&gt;Accept-Language&lt;/code&gt; and redirects a German browser to &lt;code&gt;?lang=de&lt;/code&gt;, an English one to &lt;code&gt;?lang=en&lt;/code&gt;, and so on, while a request with no language preference (most crawlers) gets the default page. Each language version has its own canonical URL and &lt;code&gt;hreflang&lt;/code&gt; links, so search engines can index all of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. A knowledge base is part of the product
&lt;/h2&gt;

&lt;p&gt;Most visitors don't arrive wanting a simulator. They arrive asking "how will my tattoo look in 20 years?", "does fine line fade?" or "how many laser sessions will I need?". Answering those questions properly, in articles with sources and illustrations, turned out to be the best way to explain why a preview is worth trying.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The previews are AI estimates of how ink, skin and sun usually behave, not a measurement of anyone's skin, and I say that on every result. I'm working on making the aging steps more consistent between styles.&lt;/p&gt;

&lt;p&gt;If you try it, I'd really like to hear what would make the aging previews more convincing to you: &lt;a href="https://inkage.app/?lang=en" rel="noopener noreferrer"&gt;inkage.app&lt;/a&gt;.&lt;/p&gt;

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