<?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: MinJian</title>
    <description>The latest articles on DEV Community by MinJian (@mileschen).</description>
    <link>https://dev.to/mileschen</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%2F4102816%2Fda4ae459-1c41-4da8-b51d-33952f825f69.png</url>
      <title>DEV Community: MinJian</title>
      <link>https://dev.to/mileschen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mileschen"/>
    <language>en</language>
    <item>
      <title>I Built a Six-Language B2B Site With AI. Checking the Result Was the Hard Part.</title>
      <dc:creator>MinJian</dc:creator>
      <pubDate>Thu, 05 Nov 2026 03:31:37 +0000</pubDate>
      <link>https://dev.to/mileschen/i-built-a-six-language-b2b-site-with-ai-checking-the-result-was-the-hard-part-1kge</link>
      <guid>https://dev.to/mileschen/i-built-a-six-language-b2b-site-with-ai-checking-the-result-was-the-hard-part-1kge</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: this article was written with AI assistance and checked against the project files and recorded implementation work. I am the website owner; this is a project-owner retrospective.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I used AI assistance to build a website for a small B2B mold-supply business. The stack is React and Vite, with prerendered public pages and a Cloudflare Worker backend. The site now has English, Simplified Chinese, Thai, Vietnamese, Arabic, and Korean versions.&lt;/p&gt;

&lt;p&gt;The work that needed the most attention happened after a feature first appeared to be finished: translated states still contained English, images disappeared from a section, navigation spacing looked wrong, and an analytics integration was collecting data without a project card appearing in its dashboard.&lt;/p&gt;

&lt;p&gt;The site is &lt;a href="https://exactmec.com/" rel="noopener noreferrer"&gt;EXACTMEC&lt;/a&gt;, used here as the concrete case behind these lessons. Its purpose is to help visitors understand a mold project and make an inquiry. This article covers the website implementation, not manufacturing advice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb36czn59nd3p5rq69sgr.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb36czn59nd3p5rq69sgr.webp" alt="Illustration of a die casting mold and matching component used on the project website" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Illustrative visual from the project website, not a photograph of a delivered customer project.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1. A translation dictionary is only the beginning
&lt;/h2&gt;

&lt;p&gt;The first Chinese version exposed an easy mistake: translating the main page copy while missing text generated by application states.&lt;/p&gt;

&lt;p&gt;The customer area still showed labels such as “Need information” and an English empty-state heading. Another page retained “We do.” Those strings were short, easy to overlook, and visible during ordinary use.&lt;/p&gt;

&lt;p&gt;The useful unit of review became a &lt;strong&gt;route × state × language&lt;/strong&gt; combination:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;States worth checking&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Navigation&lt;/td&gt;
&lt;td&gt;Closed, expanded, narrow-screen menu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inquiry list&lt;/td&gt;
&lt;td&gt;Empty, populated, filtered, loading, error&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inquiry detail&lt;/td&gt;
&lt;td&gt;Missing information, saved information, update feedback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sign-in&lt;/td&gt;
&lt;td&gt;Initial form, code entry, expired or invalid code&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Dynamic messages also need translation before inserting their changing values. Translating a static list of complete sentences cannot reliably cover a countdown or a heading with an appended status.&lt;/p&gt;

&lt;p&gt;Arabic added another dimension: right-to-left layout. Logical spacing properties helped, but account controls, arrows, numbers, and language switching still needed actual inspection. A translated string did not prove that the surrounding layout worked.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. “No overlap” is a lower bar than “looks right”
&lt;/h2&gt;

&lt;p&gt;The navigation went through several revisions. At one point it passed checks for horizontal overflow, yet the menu still looked too spread out.&lt;/p&gt;

&lt;p&gt;The cause was a mismatch between the layout rule and the intended appearance. Fixed gaps inside the menu were combined with automatic distribution of spare space elsewhere in the header. Changing one gap did not control the entire row.&lt;/p&gt;

&lt;p&gt;The eventual desktop direction was specific: keep the logo at the left, push the continuous sequence of menu and account controls toward the right, slightly reduce the text size, and increase its weight.&lt;/p&gt;

&lt;p&gt;Here is a simplified version of that rule, without the project's selector and breakpoint overrides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.header-inner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.wordmark&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;margin-inline-end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.main-navigation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part was deciding &lt;strong&gt;where extra space should go&lt;/strong&gt;. The auto margin puts it after the logo; it does not stretch the distances between the five content categories.&lt;/p&gt;

&lt;p&gt;The final desktop check covered six languages at four widths. That gave evidence about overlap and overflow. The visual decision still came from looking at the rendered header, including the longer English and Thai labels.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Illustrations need a clear boundary from real engineering files
&lt;/h2&gt;

&lt;p&gt;A generic 3D rendering looked attractive, but did not explain what product information a visitor should prepare. The examples became more useful when they showed dimensions, units, and revision information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzyodfzun1yrv2nmprqjz.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzyodfzun1yrv2nmprqjz.webp" alt="Illustrative 2D enclosure parameter sheet with dimensions, units and revision information" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;AI-generated reference example. Not a customer drawing or a drawing approved for manufacturing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftuk5xw6rk5iwo3ir9lt4.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftuk5xw6rk5iwo3ir9lt4.webp" alt="Illustrative 3D enclosure parameter view with overall dimensions and a parameter table" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;AI-generated reference example. The labels explain what information a reference might contain; the image does not establish engineering correctness.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That distinction matters in the interface. A parameter table drawn into an image is not a validated CAD model. These examples need explicit labeling, and a visitor's actual project files need their own review.&lt;/p&gt;

&lt;p&gt;The website also provides enlarged views, a fit-to-screen option, and scrolling at original size. Those interactions matter more than simply placing a detailed image inside a small card.&lt;/p&gt;

&lt;p&gt;For localization, image text deserves its own inventory. Translating the caption does not translate words embedded in the image.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Measure the action the business actually needs
&lt;/h2&gt;

&lt;p&gt;A conventional sales dashboard was not the right starting point for this site. The useful questions were simpler:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many daily visitors were counted?&lt;/li&gt;
&lt;li&gt;Which countries and cities were represented?&lt;/li&gt;
&lt;li&gt;Did someone click WhatsApp or submit an inquiry?&lt;/li&gt;
&lt;li&gt;Which verified account was observed when a signed-in action occurred?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The labels need to stay precise. A WhatsApp click does not prove that a message was sent. A daily deduplicated network IP is not a verified person: multiple people can share a connection, and an address can change. Location is an estimate.&lt;/p&gt;

&lt;p&gt;Keeping those distinctions in the dashboard prevents a clean-looking number from promising more than the measurement supports.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. SDK installation and dashboard setup are separate acceptance checks
&lt;/h2&gt;

&lt;p&gt;Ahrefs was the clearest example. Its setup screen reported that visitors were already being counted. However, the website still had no card in the workspace's project list.&lt;/p&gt;

&lt;p&gt;The remaining work was in the account workflow: finish creating the project, verify ownership through a public DNS TXT record, and complete the final settings. After that, the Web Analytics card appeared and showed existing data. The website's tracking code did not need to be replaced.&lt;/p&gt;

&lt;p&gt;That experience changed the acceptance checklist:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is the expected integration present in the deployed build?&lt;/li&gt;
&lt;li&gt;Does it respect the site's measurement choice and route boundaries?&lt;/li&gt;
&lt;li&gt;Does the provider report receiving data?&lt;/li&gt;
&lt;li&gt;Is the intended project actually available in the intended workspace?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A script tag, a successful request, and a visible dashboard are different pieces of evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would carry into the next language release
&lt;/h2&gt;

&lt;p&gt;AI assistance made implementation faster, but it did not make “finished” a reliable visual or operational judgment. The project still needed concrete checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review industry terminology and proper company names separately from general prose.&lt;/li&gt;
&lt;li&gt;Exercise dynamic states, not just the homepage.&lt;/li&gt;
&lt;li&gt;Inspect images, captions, and embedded image text.&lt;/li&gt;
&lt;li&gt;Check long labels, narrow screens, and right-to-left layouts.&lt;/li&gt;
&lt;li&gt;Keep business events distinct from outcomes they cannot prove.&lt;/li&gt;
&lt;li&gt;Finish provider-side setup before calling an integration complete.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this project, a useful acceptance question became: &lt;strong&gt;Can I point to the rendered state or provider result that proves this particular part works?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>i18n</category>
    </item>
    <item>
      <title>Building Paper Adventure: a printable game app with React, Cloudflare, and Stripe</title>
      <dc:creator>MinJian</dc:creator>
      <pubDate>Mon, 26 Oct 2026 01:42:55 +0000</pubDate>
      <link>https://dev.to/mileschen/building-paper-adventure-a-printable-game-app-with-react-cloudflare-and-stripe-21p6</link>
      <guid>https://dev.to/mileschen/building-paper-adventure-a-printable-game-app-with-react-cloudflare-and-stripe-21p6</guid>
      <description>&lt;p&gt;I'm building &lt;a href="https://paperadventure.app/en/" rel="noopener noreferrer"&gt;Paper Adventure Workshop&lt;/a&gt;, a web app for printable story adventures for families and classrooms. An adult downloads the game, prepares the paper materials, and guides children through five connected checkpoints.&lt;/p&gt;

&lt;p&gt;There are two product paths: ready-made games with existing files, and AI-assisted custom adventures built around a buyer's idea. Both need a Player Pack and a separate Host or Teacher Guide, with A4 and US Letter options.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4uz02bt58m1kpxy51oxf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4uz02bt58m1kpxy51oxf.jpg" alt="Paper Adventure Workshop homepage with its printable adventure introduction and paper-art illustration" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The live homepage introduces the print-first experience: a story, connected paper clues, and a separate adult guide.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This case study documents the engineering decisions behind turning generated content into a downloadable product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React and Vite&lt;/strong&gt; for the interface, with pre-rendered public pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Workers&lt;/strong&gt; for the API and site delivery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D1&lt;/strong&gt; for orders, saved generation progress, entitlements, and support records.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private R2 storage&lt;/strong&gt; for purchased files and generated covers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Queues&lt;/strong&gt; for background generation work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stripe Checkout and webhooks&lt;/strong&gt; for payments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The public catalogue and the private purchase flow have different jobs. Visitors should be able to explore a story before signing in. Purchased files need server-side ownership and access checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the product looks like
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A ready-made story page
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbpybb7lwhuscqalxhzq6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbpybb7lwhuscqalxhzq6.jpg" alt="The Little Dinosaur's Way Home product page, showing the story introduction and dinosaur illustration" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Dinosaur Home page gives the story context and group information before the purchase flow. The artwork introduces the world; the printable activities are explained further down the page.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A separate custom adventure flow
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9t1u9icbojm7xkf2ot9x.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9t1u9icbojm7xkf2ot9x.jpg" alt="Custom adventure creation page showing the introduction and Your idea, Your group, Optional details, Review and price steps" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The custom path starts with an idea and group preferences. It makes the sequence explicit: personal plan after payment, then PDFs after the adult approves the plan. This capture shows the public introduction and step navigation.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Treat payment and delivery as separate states
&lt;/h2&gt;

&lt;p&gt;A successful redirect from a checkout page is not enough to unlock a file. The backend needs to confirm the payment and associate it with the correct order.&lt;/p&gt;

&lt;p&gt;After that, a ready-made game and a custom game take different paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ready-made:
confirmed payment -&amp;gt; entitlement -&amp;gt; existing downloadable files

Custom:
confirmed payment -&amp;gt; saved plan -&amp;gt; adult approval
                  -&amp;gt; background generation -&amp;gt; checked PDFs -&amp;gt; downloads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That distinction also matters in the interface. "Payment confirmed," "Generating," and "Files ready" should not be interchangeable labels. If generation stops, the paid order needs to stay visible with an explanation and a support path.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Save progress before moving to the next generation step
&lt;/h2&gt;

&lt;p&gt;A single long-running request is an awkward place to build a complete game. If the final step fails, restarting everything can repeat work and spend more provider credit.&lt;/p&gt;

&lt;p&gt;The custom flow saves progress between generation steps. Background jobs resume from saved work, and retries have bounded budgets. A queue message advances a generation step instead of asking the browser to wait for the whole process.&lt;/p&gt;

&lt;p&gt;One particularly useful boundary is between checked game content and PDF rendering. A rendering failure should be able to reuse saved content rather than request another story.&lt;/p&gt;

&lt;p&gt;The principle applies beyond games: save expensive, validated intermediate results before starting the next fallible operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. A generated story still needs a game contract
&lt;/h2&gt;

&lt;p&gt;A printable adventure needs more than an interesting premise. Players need materials they can handle, instructions they can follow, and clues that support an answer.&lt;/p&gt;

&lt;p&gt;The implementation uses structured game data, deterministic puzzle checks, and paired PDF checks around the generated narrative. The player materials and adult answers have to agree. A story sentence should not imply that a clue exists when it was never printed.&lt;/p&gt;

&lt;p&gt;This also affects product design. Home and Classroom editions have distinct stories and adult guidance, rather than being the same PDF with a different label.&lt;/p&gt;

&lt;p&gt;Automated checks help catch contradictions and layout problems. Testing a printed game with real people is a separate part of evaluating its play quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Keep optional cover generation separate from the purchased files
&lt;/h2&gt;

&lt;p&gt;The game cover and the game PDFs are separate outputs. A failed cover request should not remove access to a completed game.&lt;/p&gt;

&lt;p&gt;This separation became especially concrete during development: failed historical cover requests left some library cards without illustrations even though their PDFs were available. Fixing a provider integration does not automatically repair every old record.&lt;/p&gt;

&lt;p&gt;The lesson was to keep optional asset status explicit and handle historical recovery deliberately. Repeated refreshes should not keep submitting new paid image requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Design the download and support experience together
&lt;/h2&gt;

&lt;p&gt;Once files are ready, the page should make the next action obvious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A complete ZIP as the main download.&lt;/li&gt;
&lt;li&gt;One paper-size selection for the matching files.&lt;/li&gt;
&lt;li&gt;Separate Player Pack and adult-guide downloads.&lt;/li&gt;
&lt;li&gt;A compact receipt and clear online access expiry.&lt;/li&gt;
&lt;li&gt;Order-linked help without asking the buyer to retype an order reference.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Support is part of delivery. Recording a request, notifying the operator, reviewing a refund request, and actually completing a refund are different events. The interface should describe the event that has happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd like feedback on
&lt;/h2&gt;

&lt;p&gt;For developers who have shipped generated documents or other asynchronous digital products: where do you draw the boundary between automatic recovery and an explicit user action? I'd also welcome feedback on making a print-first product understandable in a web interface.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: Paper Adventure is my project. An AI agent prepared this article from the project's implementation and development notes at my request.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>Building a 10-language B2B site: the localization bugs our code checks missed</title>
      <dc:creator>MinJian</dc:creator>
      <pubDate>Sat, 24 Oct 2026 02:48:48 +0000</pubDate>
      <link>https://dev.to/mileschen/building-a-10-language-b2b-site-the-localization-bugs-our-code-checks-missed-db6</link>
      <guid>https://dev.to/mileschen/building-a-10-language-b2b-site-the-localization-bugs-our-code-checks-missed-db6</guid>
      <description>&lt;p&gt;We built &lt;a href="https://customsignforge.com/" rel="noopener noreferrer"&gt;Custom Sign Forge&lt;/a&gt; as a B2B website for custom commercial signage. The public site has ten language versions and six product families. The implementation uses Astro and React on Cloudflare Workers, with D1 for application data and private R2 storage for uploads.&lt;/p&gt;

&lt;p&gt;The interesting part was not adding a language switcher. It was keeping the product pages, imagery, enquiry flow, and search metadata coherent as the site grew. Here are the lessons that would carry into another multilingual build.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Keep locale routing explicit
&lt;/h2&gt;

&lt;p&gt;English uses the original URLs; other languages have prefixes such as /zh/, /pt-br/, and /ar/. We do not redirect visitors based on IP address or browser language. A visitor can choose a language and share a stable URL.&lt;/p&gt;

&lt;p&gt;One routing module owns the conversion between equivalent pages. Product slugs and internal field codes remain stable. A language change updates the visible text and labels, but it does not rewrite customer-entered text or change the underlying enquiry record. This separation matters when a customer starts an enquiry in one language and returns in another.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Translation coverage is a UI problem, too
&lt;/h2&gt;

&lt;p&gt;A dictionary can be complete while the interface is not. We found untranslated navigation text in the Arabic account menu. We also caught a wrong flag next to a language label. Neither would be found by a simple check that counts translated strings.&lt;/p&gt;

&lt;p&gt;We now treat the header, account menu, validation messages, upload controls, policy links, and enquiry summary as part of every locale's acceptance criteria. For Arabic, the check also includes RTL layout, icon direction, mixed Latin/Arabic text, and alignment. We keep the actual language name visible because a flag alone is a poor identifier for a language used in multiple countries.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe218pessl11v7rcttbto.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe218pessl11v7rcttbto.png" alt="Arabic homepage showing the right-to-left navigation and hero layout" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Arabic homepage screenshot: the navigation and hero follow a right-to-left layout. The storefront scene is a labelled design concept.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Image composition needs its own content model
&lt;/h2&gt;

&lt;p&gt;Our first Chinese product layouts exposed a familiar problem: applying the same fixed image box and object-fit: cover rule to every asset. Some signage photos are wide; others are close-ups or portrait compositions. A uniform crop can remove the sign itself. Switching every image to contain is not enough either; it may create awkward empty bands.&lt;/p&gt;

&lt;p&gt;We changed the gallery approach instead. Each image gets a frame appropriate to its purpose and source aspect ratio. Product design concepts use consistent 4:3 compositions; wide construction photographs keep their native proportions. On mobile, the grid becomes a single column, and the enquiry action stays easy to reach before a long image sequence. We also label generated design concepts as concepts rather than implying that they are photographs of completed customer projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzw7pcb67zkaz7b32vtev.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzw7pcb67zkaz7b32vtev.png" alt="Chinese LED channel letters page with a two-column design gallery" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Chinese product-page screenshot: equal landscape frames make the design concepts comparable without cropping away the signs. These are design inspirations, not completed customer installations.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The reusable rule: decide whether an image is a hero, a comparison, a detail, or evidence before choosing its crop behavior. Inspect the actual focal point at desktop and phone widths.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Search metadata is part of localization
&lt;/h2&gt;

&lt;p&gt;Each public locale page renders its own HTML language, title, description, H1, and canonical URL. Equivalent pages carry reciprocal hreflang links, and the sitemap includes locale alternates. Private account and admin paths are kept out of the public index. This prevents the common failure where a translated page looks localized but still advertises the English canonical URL.&lt;/p&gt;

&lt;p&gt;A sitemap submission is only a discovery signal, not a guarantee of indexing. We still check the live HTML, response status, robots rules, and Search Console reports after deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Share the business flow; localize its presentation
&lt;/h2&gt;

&lt;p&gt;The quote form uses shared sessions, CSRF protection, stable field codes, and private attachments across languages. The submitted locale is stored with the enquiry, while the original customer wording remains untouched. A language-only retry reuses the existing idempotency key so it does not create a duplicate enquiry.&lt;/p&gt;

&lt;p&gt;This gave us one set of business rules to test, with a separate presentation layer for each language. It also exposed the places that need real browser testing: sign-in return paths, draft restoration, optional uploads, validation, and account summaries.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Test the rendered pages, not just the translation files
&lt;/h2&gt;

&lt;p&gt;For each new locale, our release checklist now combines automated checks with a small visual matrix: homepage, product index, all six product detail pages, account menu, quote flow, and mobile header. We inspect long headings, contrast, missing images, focal-point crops, and language leaks. Arabic adds RTL-specific checks.&lt;/p&gt;

&lt;p&gt;The broader lesson is that internationalization is a product quality discipline. A locale is ready when its content, layout, interaction, and search signals work together—not when the JSON file is filled.&lt;/p&gt;

&lt;p&gt;Disclosure: This article was generated by an AI agent from the project's source and implementation notes. Factual implementation details were checked against those materials. It is a technical case study, not a claim that AI-generated concept images are completed customer installations.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>astro</category>
      <category>i18n</category>
      <category>seo</category>
    </item>
    <item>
      <title>Building FitRooted: a fitness knowledge library organized around questions</title>
      <dc:creator>MinJian</dc:creator>
      <pubDate>Sun, 04 Oct 2026 02:40:42 +0000</pubDate>
      <link>https://dev.to/mileschen/building-fitrooted-a-fitness-knowledge-library-organized-around-questions-497d</link>
      <guid>https://dev.to/mileschen/building-fitrooted-a-fitness-knowledge-library-organized-around-questions-497d</guid>
      <description>&lt;p&gt;A product can have useful content and still make it difficult to know where to start. That’s the design problem I’m working on with FitRooted.&lt;br&gt;
It’s a fitness and fat-loss knowledge library, with a complementary Chinese wellness section. The core is the knowledge, not a chatbot.&lt;/p&gt;

&lt;p&gt;Website: &lt;a href="https://fitrooted.com/" rel="noopener noreferrer"&gt;https://fitrooted.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvb659ep8g557iiz687jc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvb659ep8g557iiz687jc.png" alt=" " width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The challenge is presenting those parts without making the homepage look like a directory of everything the site can do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions first, categories second&lt;/strong&gt;&lt;br&gt;
The library uses everyday questions as entry points: starting strength training, fitting exercise into two days a week, or restarting after a break.&lt;br&gt;
My working assumption is that a specific question can be easier to recognize than a broad category. Someone may not know which training topic they need, but they can recognize their own situation.&lt;br&gt;
Categories still have a job. They give someone who wants to browse a map of the content. I don’t want a question-first design to become search-only navigation.&lt;br&gt;
The trade-off is repetition. Several questions can lead to almost the same explanation. A useful review question for this kind of library is: does each new page address a different situation, or just rephrase an existing headline?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Put the source within reach of the answer&lt;/strong&gt;&lt;br&gt;
One published example asks: “How should I combine strength training and cardio?”&lt;br&gt;
You can see the page here:&lt;br&gt;
&lt;a href="https://fitrooted.com/answers/strength-and-cardio" rel="noopener noreferrer"&gt;https://fitrooted.com/answers/strength-and-cardio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyx53wvx1xvzwdr417nmh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyx53wvx1xvzwdr417nmh.png" alt=" " width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The page presents a short answer and names Physical Activity Guidelines for Americans as a supporting source.&lt;br&gt;
That doesn’t make the answer automatically correct. A citation still needs to support the claim being made. But it gives the reader something specific to inspect rather than a generic promise that the content is trustworthy.&lt;br&gt;
The interface trade-off is how much to show immediately. Too little context makes the answer hard to assess; too much can overwhelm someone who only needs a starting point.&lt;br&gt;
My design goal is a readable short answer with an obvious route to its supporting material, rather than forcing the reader to choose between simplicity and transparency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep the main subject clear&lt;/strong&gt;&lt;br&gt;
The Chinese wellness section covers movement, everyday routines, food and seasonal ideas. It sits alongside the fitness and fat-loss library, rather than replacing it.&lt;br&gt;
That section is here:&lt;br&gt;
&lt;a href="https://fitrooted.com/knowledge/chinese-wellness" rel="noopener noreferrer"&gt;https://fitrooted.com/knowledge/chinese-wellness&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsoebscn4g8lpcvs3dnhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsoebscn4g8lpcvs3dnhg.png" alt=" " width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This distinction matters to the navigation. Someone arriving with a strength-training question should immediately understand where to go. Someone exploring Chinese wellness should be able to follow that path without confusing lifestyle content with medical advice.&lt;br&gt;
AI has a supporting role, too. I want it to help people explore knowledge, not make the whole product feel like a blank chat box. The library should still make sense to someone who never opens the AI feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The navigation question I’d like feedback on&lt;/strong&gt;&lt;br&gt;
For this kind of content-heavy product, would you make common questions, topic categories, or a short guided starting point the most prominent entry on the homepage?&lt;br&gt;
I’m particularly interested in the trade-off between helping a first-time visitor and keeping navigation efficient for someone returning to a specific answer.&lt;br&gt;
I’d test that by giving people one concrete question and watching where they look first, rather than assuming a cleaner-looking homepage is automatically easier to use.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>ux</category>
      <category>webdev</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>I Built HSKKit: A Different Way to Learn HSK 3.0 Vocabulary</title>
      <dc:creator>MinJian</dc:creator>
      <pubDate>Mon, 14 Sep 2026 02:43:33 +0000</pubDate>
      <link>https://dev.to/mileschen/i-built-hskkit-a-different-way-to-learn-hsk-30-vocabulary-585f</link>
      <guid>https://dev.to/mileschen/i-built-hskkit-a-different-way-to-learn-hsk-30-vocabulary-585f</guid>
      <description>&lt;p&gt;Learning Chinese vocabulary looks simple at first.&lt;/p&gt;

&lt;p&gt;You get a word list, memorize the words, and move on to the next level.&lt;/p&gt;

&lt;p&gt;But while looking at how HSK learners actually study, I noticed a problem: having access to thousands of words is not the same as having a clear learning path.&lt;/p&gt;

&lt;p&gt;A learner might have a vocabulary list, a flashcard app, a dictionary, a listening resource, and a mock test — but these tools often exist separately.&lt;/p&gt;

&lt;p&gt;That was the problem I wanted to explore when building HSKKit.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3wmzty71ksfx80lootzr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3wmzty71ksfx80lootzr.png" alt=" " width="800" height="572"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem I wanted to solve&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The new HSK 3.0 framework introduces a much larger vocabulary system across Levels 1–9.&lt;/p&gt;

&lt;p&gt;For someone preparing for HSK, several questions appear very quickly:&lt;/p&gt;

&lt;p&gt;What level should I start from?&lt;br&gt;
Which vocabulary should I learn today?&lt;br&gt;
When should I review a word?&lt;br&gt;
How do I know which words I keep getting wrong?&lt;br&gt;
How can I combine vocabulary and listening practice?&lt;br&gt;
How do I avoid repeatedly studying words I already know?&lt;/p&gt;

&lt;p&gt;A static vocabulary list doesn't really solve these problems.&lt;/p&gt;

&lt;p&gt;So instead of building another directory of HSK words, I wanted to experiment with a more connected study workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I built&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The result is HSKKit, a web-based learning platform organized around published HSK 3.0 vocabulary.&lt;/p&gt;

&lt;p&gt;The current workflow connects several parts of studying:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Placement → Vocabulary → Listening → Practice → Review → Mistakes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learners can first find a practical starting level and then move into vocabulary organized by HSK level or topic.&lt;/p&gt;

&lt;p&gt;The platform currently includes HSK 3.0 Levels 1–9, with Chinese characters, pinyin, English meanings, listening practice where audio is available, and a searchable dictionary.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4hlpv8yg579ejk7smf7k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4hlpv8yg579ejk7smf7k.png" alt=" " width="800" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The interesting part: deciding what to review&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the biggest design decisions was not simply what content to show, but when to bring content back.&lt;/p&gt;

&lt;p&gt;If someone already remembers a word easily, showing it again tomorrow isn't very useful.&lt;/p&gt;

&lt;p&gt;If they repeatedly forget another word, that word deserves more attention.&lt;/p&gt;

&lt;p&gt;That's why I added a spaced-repetition-style review flow.&lt;/p&gt;

&lt;p&gt;Instead of treating every vocabulary item equally, the study experience tries to bring words back when they actually need another review.&lt;/p&gt;

&lt;p&gt;Mistakes are also kept in the learning loop rather than disappearing after a practice session.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foobz5svw0ttg0lms3zby.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foobz5svw0ttg0lms3zby.png" alt=" " width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning by situations instead of only levels&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another thing I wanted to experiment with was topic-based learning.&lt;/p&gt;

&lt;p&gt;HSK levels are useful for exam preparation, but people don't experience a language as "Level 1 words" and "Level 2 words" in real life.&lt;/p&gt;

&lt;p&gt;They experience situations.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;getting ready in the morning&lt;br&gt;
staying at a hotel&lt;br&gt;
doing household chores&lt;br&gt;
making plans&lt;br&gt;
travelling&lt;br&gt;
ordering food&lt;/p&gt;

&lt;p&gt;So HSKKit also groups vocabulary into practical situations while keeping the words connected to their published HSK levels.&lt;/p&gt;

&lt;p&gt;This creates two possible paths:&lt;/p&gt;

&lt;p&gt;Exam-oriented: learn by HSK level.&lt;/p&gt;

&lt;p&gt;Usage-oriented: learn vocabulary through real-world topics.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd5nakygeqing2da528ny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd5nakygeqing2da528ny.png" alt=" " width="800" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI without replacing the source material&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I also wanted to be careful about how AI is used.&lt;/p&gt;

&lt;p&gt;For a language-learning product, simply asking an LLM to generate unlimited vocabulary or definitions introduces an obvious problem: the learner may not know whether the generated material actually belongs to the HSK standard.&lt;/p&gt;

&lt;p&gt;So the core vocabulary catalog is source-controlled rather than freely generated by AI.&lt;/p&gt;

&lt;p&gt;AI-assisted features can help around the learning experience, while the underlying HSK vocabulary remains tied to the published dataset.&lt;/p&gt;

&lt;p&gt;This separation became an important product decision:&lt;/p&gt;

&lt;p&gt;Use AI to improve the learning experience, not to invent the curriculum.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned while building it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The biggest lesson for me was that an educational product doesn't necessarily need more content.&lt;/p&gt;

&lt;p&gt;Sometimes it needs better connections between existing content.&lt;/p&gt;

&lt;p&gt;A vocabulary database is useful.&lt;/p&gt;

&lt;p&gt;A listening tool is useful.&lt;/p&gt;

&lt;p&gt;A flashcard system is useful.&lt;/p&gt;

&lt;p&gt;A placement test is useful.&lt;/p&gt;

&lt;p&gt;But connecting them into one continuous path can make the product much easier to understand:&lt;/p&gt;

&lt;p&gt;Where am I? → What should I learn? → Can I recognize it? → Can I hear it? → When should I review it?&lt;/p&gt;

&lt;p&gt;That's the direction I'm continuing to explore.&lt;/p&gt;

&lt;p&gt;I built the project here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HSKKit:&lt;/strong&gt; &lt;a href="https://hskkit.com/" rel="noopener noreferrer"&gt;https://hskkit.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd especially be interested in feedback from developers who have worked on EdTech, language-learning products, spaced repetition, or AI-assisted learning.&lt;/p&gt;

&lt;p&gt;What would you improve about this learning flow?&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>ai</category>
      <category>education</category>
    </item>
    <item>
      <title>I Built an AI Career Test That Gives You Career Hypotheses, Not a Career Verdict</title>
      <dc:creator>MinJian</dc:creator>
      <pubDate>Sat, 05 Sep 2026 03:42:39 +0000</pubDate>
      <link>https://dev.to/mileschen/i-built-an-ai-career-test-that-gives-you-career-hypotheses-not-a-career-verdict-ifp</link>
      <guid>https://dev.to/mileschen/i-built-an-ai-career-test-that-gives-you-career-hypotheses-not-a-career-verdict-ifp</guid>
      <description>&lt;p&gt;Career questions have become harder to answer in the AI era.&lt;br&gt;
It is no longer only about what someone is good at, what job title to pursue, or which skills to learn next. People are also asking which parts of their work AI can accelerate, whether a direction genuinely fits them or is simply popular online, and how they can test a career path before spending months on courses or making a major switch.&lt;br&gt;
That is why I built AI Career Test, a free, roughly ten minute career self exploration tool. It is designed to turn personal signals into career directions to investigate and practical next steps.&lt;br&gt;
It is not a professional assessment, career advice service, or a machine that can tell someone what job they should do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem with a single career verdict&lt;/strong&gt;&lt;br&gt;
A result such as You should become a product designer can sound decisive, but it hides too much uncertainty.&lt;br&gt;
A useful career exploration tool should look beyond a single personality label. It should help someone examine the combination of interests and work values, strengths and preferred ways of working, personality and collaboration signals, current skills, and AI era preferences such as learning, judgment, privacy awareness, and adaptability.&lt;br&gt;
Even then, the result should be treated as a working hypothesis, not a prediction.&lt;br&gt;
A test cannot know someone’s finances, location, qualifications, health, responsibilities, or the real hiring conditions in their market. It can help organize the signals already present and turn them into questions worth testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From assessment signals to an action plan&lt;/strong&gt;&lt;br&gt;
The free assessment contains 40 questions and uses a simple response scale rather than asking users to write a long biography.&lt;br&gt;
The goal is not to label people. It is to help them reflect on patterns such as the kinds of problems they enjoy, their preferred work environment, whether they gain energy from analysis, creativity, collaboration, or execution, and what role AI should play in their work.&lt;br&gt;
The result should lead to a better question than What is my perfect career. A more useful question is Which career directions are credible enough for me to validate next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjm8leh3bteb14vru00is.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjm8leh3bteb14vru00is.png" alt=" " width="644" height="572"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What a complete report should explain&lt;/strong&gt;&lt;br&gt;
The sample report on the site is intentionally fictional and marked as illustrative data. It demonstrates the kind of information I think a career report should provide.&lt;br&gt;
A working hypothesis in plain language, including the strongest patterns and the uncertainty that remains.&lt;br&gt;
Evidence linked career matches, with an explanation of why a path may fit rather than only a ranked list of job titles.&lt;br&gt;
Trade offs and risks, showing what to test rather than only what looks attractive.&lt;br&gt;
Skills and AI readiness, including learning, verification of AI output, privacy awareness, and judgment.&lt;br&gt;
A 30, 60, and 90 day roadmap that creates momentum through small experiments, proof of work, and reflection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why test before you commit matters&lt;/strong&gt;&lt;br&gt;
A career match is more useful when it comes with a validation exercise.&lt;br&gt;
Instead of telling someone to immediately pivot into a new field, a better next step could be to interview someone already doing that work, compare what the role involves during a normal week, build a small project resembling an important task in the role, collect evidence for one skill gap before buying another course, or rewrite one resume bullet around a real outcome instead of a generic responsibility.&lt;br&gt;
The goal is to reduce blind commitment. Career exploration should move from vague self description to observable evidence. What work do I actually enjoy doing repeatedly. What can I show. What assumptions about a role have I tested.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building around explainability&lt;/strong&gt;&lt;br&gt;
I wanted the product to make its limits visible. The site states that results are for self exploration, not professional assessment or career advice. The sample report also distinguishes between a recommendation, an uncertainty, and a next experiment.&lt;br&gt;
AI can make reflection faster. It can help organize signals and reveal options people may not have considered. But it should not replace a person’s lived context, responsibility, or decision making.&lt;br&gt;
The best outcome is not that the AI chose my career. The better outcome is that I have a clearer direction, understand why it may fit, and know the next small experiment to run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdrbja1p5zdjevosbplvw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdrbja1p5zdjevosbplvw.png" alt=" " width="577" height="791"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try the free assessment&lt;/strong&gt;&lt;br&gt;
If you want to try the free assessment or inspect the illustrative report structure, visit &lt;a href="https://aicareertest.work/" rel="noopener noreferrer"&gt;https://aicareertest.work/&lt;/a&gt;&lt;br&gt;
I would also love to hear from developers and career changers. What would make you trust an AI assisted career exploration tool, and what would immediately make you distrust one?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>showdev</category>
      <category>interview</category>
    </item>
  </channel>
</rss>
