From b330583dd336dfd77a942a1fbf4cdc35872093f4 Mon Sep 17 00:00:00 2001 From: Arnaud Date: Tue, 14 Jul 2026 15:21:15 +0200 Subject: [PATCH] fix: detect imported recipe language for Translate button (v0.33.1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit URL import extracts content in the source page's own language (no translation), but never recorded what that language was, so the Translate button's "recipe.language !== my locale" check always saw null and showed the button unconditionally. The extractor now returns a detected ISO 639-1 language code alongside the recipe. Photo import always writes in the caller's locale already (see its langInstruction) but never recorded that either — now sets it directly to locale since it's known, not detected. Co-Authored-By: Claude Sonnet 5 --- CHANGELOG.md | 5 +++++ apps/web/app/api/v1/ai/import-photo/route.ts | 6 ++++++ apps/web/lib/ai/features/import-url.ts | 3 ++- apps/web/lib/changelog.ts | 9 ++++++++- apps/web/package.json | 2 +- package.json | 2 +- 6 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e552fc6..e03de8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to Epicure are documented here. This file is mirrored in-app at `/changelog` (and in the admin dashboard) via `apps/web/lib/changelog.ts` — update both together. +## 0.33.1 — 2026-07-14 17:45 + +### Fixed +- URL-imported recipes never recorded what language they were actually written in, so the Translate button couldn't tell whether translation was needed — the importer now detects the source page's language, and photo import records the language it always writes in. + ## 0.33.0 — 2026-07-14 17:35 ### Added diff --git a/apps/web/app/api/v1/ai/import-photo/route.ts b/apps/web/app/api/v1/ai/import-photo/route.ts index 8348840..60f07f1 100644 --- a/apps/web/app/api/v1/ai/import-photo/route.ts +++ b/apps/web/app/api/v1/ai/import-photo/route.ts @@ -66,6 +66,12 @@ export async function POST(req: NextRequest) { cookMins: recipe.cookMins, dietaryTags: recipe.dietaryTags ?? {}, aiGenerated: true, + // The extraction prompt always writes the recipe in the caller's own + // locale (see importFromPhoto's langInstruction) regardless of what + // language the photo/label was in — so this *is* the recipe's + // language, not a guess, and lets the Translate button correctly + // stay hidden until the user's app language changes. + language: locale, createdAt: now, updatedAt: now, }); diff --git a/apps/web/lib/ai/features/import-url.ts b/apps/web/lib/ai/features/import-url.ts index f7d12c3..2a5686e 100644 --- a/apps/web/lib/ai/features/import-url.ts +++ b/apps/web/lib/ai/features/import-url.ts @@ -6,6 +6,7 @@ import { dietaryTagsSchema, ingredientSchema, stepSchema } from "./recipe-schema const ImportedRecipeSchema = z.object({ recipeType: z.enum(["dish", "drink"]).describe("\"drink\" only for a beverage/cocktail (no cooking step) — \"dish\" for anything else, including if unsure."), + language: z.string().min(2).max(10).describe("ISO 639-1 code of the language the recipe content (title/ingredients/steps) is actually written in, e.g. \"en\", \"fr\" — the source page's language, not a language to translate into."), title: z.string(), description: z.string().optional(), baseServings: z.number().int().min(1).optional(), @@ -42,7 +43,7 @@ export async function importFromUrl(url: string, config?: AiConfig): Promise