DEV Community

Chishan
Chishan

Posted on

Handling YMYL Content in a Serverless Next.js App: What We Got Wrong (and Right)

When we built VisaCanvas, an AI-powered immigration eligibility assessment tool, we quickly ran into a problem most web developers never think about: YMYL compliance.

What is YMYL?

YMYL stands for "Your Money or Your Life" — Google's classification for content that could impact a person's health, finances, safety, or legal standing. Immigration law sits squarely in this category.

For us, this meant every architectural decision had to account for:

  • Accuracy disclaimers that couldn't be accidentally removed
  • No caching of personalized legal assessments
  • Clear separation between AI-generated insights and legal facts

The Architecture

We chose Next.js App Router with server components for a specific reason: we needed fine-grained control over what gets statically generated vs. dynamically rendered.

// Static: educational guides that rarely change
// /guides/what-is-eb1a, /guides/what-is-niw
export const dynamic = 'force-static';

// Dynamic: personalized assessment results
// /assess
export const dynamic = 'force-dynamic';
export const revalidate = 0;
Enter fullscreen mode Exit fullscreen mode

Our guides on EB-1A eligibility and NIW criteria are statically generated — they contain factual information about USCIS standards that doesn't change per user.

But the assessment engine at /assess must be dynamic. Every response is unique, and caching someone's immigration eligibility result would be both technically wrong and ethically problematic.

Mistake #1: Forgetting Disclaimer Propagation

Our first deployment had disclaimers in a shared layout component. The problem? Some pages using generateStaticParams stripped the layout during build, causing disclaimers to disappear on certain routes.

The fix was embarrassingly simple: we moved the legal disclaimer into a server component that's explicitly imported in every page that discusses immigration criteria.

import { LegalDisclaimer } from '@/components/legal-disclaimer';

export default function AssessPage() {
  return (
    <>
      <LegalDisclaimer />
      <AssessmentForm />
      <LegalDisclaimer variant="footer" />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Disclaimer: VisaCanvas does not provide legal advice. Always consult a qualified immigration attorney for your specific situation.

Mistake #2: AI Output Without Guardrails

Early iterations let the AI scoring model return raw confidence percentages. A user seeing "87% eligible for EB-1A" could reasonably interpret that as a legal opinion.

We restructured the output to use qualitative bands:

  • Strong indicators (not "high probability")
  • Moderate indicators (not "50% chance")
  • Needs strengthening (not "unlikely to qualify")

Language matters enormously in YMYL contexts.

Mistake #3: Over-Relying on Client-Side Validation

We initially validated assessment inputs client-side only. For a tool that people use to make life-changing decisions, this was inadequate. Server-side validation with Zod schemas now catches edge cases that could lead to misleading results.

What We Got Right

  1. Edge functions for assessment processing — low latency without storing personal data longer than necessary
  2. No user accounts required — the free assessment works without creating an account, reducing the surface area for data breaches
  3. Source attribution — every criterion references the specific USCIS policy manual section

Key Takeaway

If you're building in a YMYL space, treat your disclaimers as load-bearing infrastructure, not decoration. They should be as resilient as your authentication layer.


This article reflects our technical experience building VisaCanvas. It does not constitute legal advice. For immigration questions, consult a licensed attorney.

Top comments (0)