fix: prevent Chrome auto-translate from crashing onboarding (#65)

* fix: prevent Chrome auto-translate from crashing React during onboarding

Chrome auto-translate modifies DOM text nodes when it detects a Swedish
page (lang="sv") in a browser set to English. React does not expect
external DOM mutations and throws, crashing the entire component tree
into global-error.tsx on every step transition.

Add translate="no" and <meta name="google" content="notranslate"> to
suppress browser translation. Also fix timezone-unsafe date parsing in
fiscal period validation (new Date("YYYY-MM-DD") + getDate() returns
local-timezone values, shifting dates by -1 day in Western timezones).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add notranslate meta tag to global-error.tsx for consistency

Per review feedback — global-error.tsx renders its own <html> document,
so it needs the same <meta name="google" content="notranslate"> tag as
layout.tsx to fully suppress Chrome translation on error pages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-03-20 15:11:44 +01:00
committed by GitHub
co-authored by Claude Opus 4.6
parent db528c3652
commit 99bc462315
4 changed files with 38 additions and 26 deletions
+10 -14
View File
@@ -13,7 +13,7 @@ import { InfoTooltip } from '@/components/ui/info-tooltip'
import { Loader2, ArrowRight, ArrowLeft, Check, CalendarDays } from 'lucide-react'
import { cn } from '@/lib/utils'
import { useToast } from '@/components/ui/use-toast'
import { monthsBetween } from '@/lib/bookkeeping/validate-period-duration'
import { monthsBetween, parseDateParts } from '@/lib/bookkeeping/validate-period-duration'
import type { EntityType } from '@/types'
const schema = z.object({
@@ -68,11 +68,8 @@ const monthNames = [
]
function formatSwedishDate(dateStr: string): string {
const d = new Date(dateStr)
const day = d.getDate()
const month = monthNames[d.getMonth()].toLowerCase()
const year = d.getFullYear()
return `${day} ${month} ${year}`
const { year, month, day } = parseDateParts(dateStr)
return `${day} ${monthNames[month - 1].toLowerCase()} ${year}`
}
/**
@@ -180,28 +177,28 @@ export default function Step3TaxRegistration({
// State for first-year start date selectors (month/year)
const [startMonth, setStartMonth] = useState<number>(
initialData.first_year_start
? new Date(initialData.first_year_start).getMonth() + 1
? parseDateParts(initialData.first_year_start).month
: 0
)
const [startYear, setStartYear] = useState<number>(
initialData.first_year_start
? new Date(initialData.first_year_start).getFullYear()
? parseDateParts(initialData.first_year_start).year
: 0
)
// State for AB first-year end month selector
const [abEndMonth, setAbEndMonth] = useState<number>(
initialData.first_year_end
? new Date(initialData.first_year_end).getMonth() + 1
? parseDateParts(initialData.first_year_end).month
: 12
)
// Parse first year start for date computations
const parsedStart = useMemo(() => {
if (!firstYearStart) return null
const d = new Date(firstYearStart)
if (isNaN(d.getTime())) return null
return { year: d.getFullYear(), month: d.getMonth() + 1 }
const parts = parseDateParts(firstYearStart)
if (isNaN(parts.year) || isNaN(parts.month)) return null
return { year: parts.year, month: parts.month }
}, [firstYearStart])
// Compute end date options for first year
@@ -220,8 +217,7 @@ export default function Step3TaxRegistration({
if (data.is_first_fiscal_year && data.first_year_start && data.first_year_end) {
// Derive start month from end date
const endDate = new Date(data.first_year_end)
const endMonth = endDate.getMonth() + 1
const endMonth = parseDateParts(data.first_year_end).month
fiscalYearStartMonth = endMonth === 12 ? 1 : endMonth + 1
firstStart = data.first_year_start
firstEnd = data.first_year_end