);
diff --git a/core/vibes/soul/sections/reviews/index.tsx b/core/vibes/soul/sections/reviews/index.tsx
index d248f66f2..b27c75f97 100644
--- a/core/vibes/soul/sections/reviews/index.tsx
+++ b/core/vibes/soul/sections/reviews/index.tsx
@@ -34,7 +34,10 @@ interface Props {
formReviewLabel?: string;
formNameLabel?: string;
formEmailLabel?: string;
- streamableImages: Streamable>;
+ streamableImages: Streamable<{
+ images: Array<{ src: string; alt: string }>;
+ pageInfo?: { hasNextPage: boolean; endCursor: string | null };
+ }>;
streamableProduct: Streamable<{ name: string }>;
streamableUser: Streamable<{ email: string; name: string }>;
}
@@ -212,7 +215,10 @@ export function ReviewsEmptyState({
formReviewLabel?: string;
formNameLabel?: string;
formEmailLabel?: string;
- streamableImages: Streamable>;
+ streamableImages: Streamable<{
+ images: Array<{ src: string; alt: string }>;
+ pageInfo?: { hasNextPage: boolean; endCursor: string | null };
+ }>;
streamableProduct: Streamable<{ name: string }>;
streamableUser: Streamable<{ email: string; name: string }>;
}) {
diff --git a/core/vibes/soul/sections/reviews/review-form.tsx b/core/vibes/soul/sections/reviews/review-form.tsx
index 1f72c818b..49e263c84 100644
--- a/core/vibes/soul/sections/reviews/review-form.tsx
+++ b/core/vibes/soul/sections/reviews/review-form.tsx
@@ -38,7 +38,10 @@ interface Props {
formReviewLabel?: string;
formNameLabel?: string;
formEmailLabel?: string;
- streamableImages: Streamable>;
+ streamableImages: Streamable<{
+ images: Array<{ src: string; alt: string }>;
+ pageInfo?: { hasNextPage: boolean; endCursor: string | null };
+ }>;
streamableProduct: Streamable<{ name: string }>;
streamableUser: Streamable<{ email: string; name: string }>;
}
@@ -126,8 +129,8 @@ export const ReviewForm = ({
}
value={Streamable.all([streamableProduct, streamableImages])}
>
- {([product, images]) => {
- const firstImage = images[0];
+ {([product, imagesData]) => {
+ const firstImage = imagesData.images[0];
return (
<>
diff --git a/core/vibes/soul/sections/slideshow/index.tsx b/core/vibes/soul/sections/slideshow/index.tsx
index 80594992d..f98a1c5fa 100644
--- a/core/vibes/soul/sections/slideshow/index.tsx
+++ b/core/vibes/soul/sections/slideshow/index.tsx
@@ -51,18 +51,18 @@ const useProgressButton = (
const onProgressButtonClick = useCallback(
(index: number) => {
if (!emblaApi) return;
- emblaApi.scrollTo(index);
+ emblaApi.goTo(index);
if (onButtonClick) onButtonClick(emblaApi);
},
[emblaApi, onButtonClick],
);
const onInit = useCallback((emblaAPI: EmblaCarouselType) => {
- setScrollSnaps(emblaAPI.scrollSnapList());
+ setScrollSnaps(emblaAPI.snapList());
}, []);
const onSelect = useCallback((emblaAPI: EmblaCarouselType) => {
- setSelectedIndex(emblaAPI.selectedScrollSnap());
+ setSelectedIndex(emblaAPI.selectedSnap());
}, []);
useEffect(() => {
@@ -71,7 +71,7 @@ const useProgressButton = (
onInit(emblaApi);
onSelect(emblaApi);
- emblaApi.on('reInit', onInit).on('reInit', onSelect).on('select', onSelect);
+ emblaApi.on('reinit', onInit).on('reinit', onSelect).on('select', onSelect);
}, [emblaApi, onInit, onSelect]);
return {
@@ -106,7 +106,7 @@ const useProgressButton = (
*/
export function Slideshow({ slides, playOnInit = true, interval = 5000, className }: Props) {
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true, duration: 20 }, [
- Autoplay({ delay: interval, playOnInit }),
+ Autoplay({ delay: interval, active: playOnInit }),
Fade(),
]);
const { selectedIndex, scrollSnaps, onProgressButtonClick } = useProgressButton(emblaApi);
@@ -145,7 +145,7 @@ export function Slideshow({ slides, playOnInit = true, interval = 5000, classNam
.on('autoplay:stop', () => {
setIsPlaying(false);
})
- .on('reInit', () => {
+ .on('reinit', () => {
setIsPlaying(autoplay.isPlaying());
});
}, [emblaApi, playCount]);
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index dbc27dcfc..9c6946782 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -135,17 +135,17 @@ importers:
specifier: ^3.3.1
version: 3.3.1
embla-carousel:
- specifier: 8.5.2
- version: 8.5.2
+ specifier: 9.0.0-rc01
+ version: 9.0.0-rc01
embla-carousel-autoplay:
- specifier: 8.5.2
- version: 8.5.2(embla-carousel@8.5.2)
+ specifier: 9.0.0-rc01
+ version: 9.0.0-rc01(embla-carousel@9.0.0-rc01)
embla-carousel-fade:
- specifier: 8.5.2
- version: 8.5.2(embla-carousel@8.5.2)
+ specifier: 9.0.0-rc01
+ version: 9.0.0-rc01(embla-carousel@9.0.0-rc01)
embla-carousel-react:
- specifier: 8.5.2
- version: 8.5.2(react@19.1.5)
+ specifier: 9.0.0-rc01
+ version: 9.0.0-rc01(react@19.1.5)
gql.tada:
specifier: ^1.8.10
version: 1.8.10(graphql@16.11.0)(typescript@5.8.3)
@@ -5997,28 +5997,28 @@ packages:
electron-to-chromium@1.5.165:
resolution: {integrity: sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw==}
- embla-carousel-autoplay@8.5.2:
- resolution: {integrity: sha512-27emJ0px3q/c0kCHCjwRrEbYcyYUPfGO3g5IBWF1i7714TTzE6L9P81V6PHLoSMAKJ1aHoT2e7YFOsuFKCbyag==}
+ embla-carousel-autoplay@9.0.0-rc01:
+ resolution: {integrity: sha512-gl7jUe0X9xd5v7IiyFF2FCR+KTBesnutM0gQ3S75oo9EizZi5tJMNdVaFwvzepz6kGzDkkSbKMWitQvAbFVfdQ==}
peerDependencies:
- embla-carousel: 8.5.2
+ embla-carousel: 9.0.0-rc01
- embla-carousel-fade@8.5.2:
- resolution: {integrity: sha512-QJ46Xy+mpijjquQeIY0d0sPSy34XduREUnz7tn1K20hcKyZYTONNIXQZu3GGNwG59cvhMqYJMw9ki92Rjd14YA==}
+ embla-carousel-fade@9.0.0-rc01:
+ resolution: {integrity: sha512-sIpJaJmcrp7+vm5r/XHEqDcCo5Fg29DdL/2Za5FQ2k//ePqapnPPzfUeG018uPT/6ylBjhn007s4sRkilbu2GA==}
peerDependencies:
- embla-carousel: 8.5.2
+ embla-carousel: 9.0.0-rc01
- embla-carousel-react@8.5.2:
- resolution: {integrity: sha512-Tmx+uY3MqseIGdwp0ScyUuxpBgx5jX1f7od4Cm5mDwg/dptEiTKf9xp6tw0lZN2VA9JbnVMl/aikmbc53c6QFA==}
+ embla-carousel-react@9.0.0-rc01:
+ resolution: {integrity: sha512-2ik9QtVm3UXJWkVdEEm6bInmxNSmxq9Z2q5GWuJx3v2vZvujmlDzcrIE6bvh+wWgPmDn6jekJCRHm1eEl/N0SA==}
peerDependencies:
react: ^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
- embla-carousel-reactive-utils@8.5.2:
- resolution: {integrity: sha512-QC8/hYSK/pEmqEdU1IO5O+XNc/Ptmmq7uCB44vKplgLKhB/l0+yvYx0+Cv0sF6Ena8Srld5vUErZkT+yTahtDg==}
+ embla-carousel-reactive-utils@9.0.0-rc01:
+ resolution: {integrity: sha512-RnW0NMrL7wVAQb9jro+l96hLI2JairyFHS2Jv+fvXakveD/c5aD9aoNH94YRbTmi0G7PxrKSxydmCpTy5eFmrA==}
peerDependencies:
- embla-carousel: 8.5.2
+ embla-carousel: 9.0.0-rc01
- embla-carousel@8.5.2:
- resolution: {integrity: sha512-xQ9oVLrun/eCG/7ru3R+I5bJ7shsD8fFwLEY7yPe27/+fDHCNj0OT5EoG5ZbFyOxOcG6yTwW8oTz/dWyFnyGpg==}
+ embla-carousel@9.0.0-rc01:
+ resolution: {integrity: sha512-4BTERU1gAXgg4Vl0m7hQ1GzePGLNNfM2j030ww8i9idiPXumyRUpaNUDfT2zx1Hv8um1Ew7QKBy/HdNPz8L30g==}
emittery@0.13.1:
resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
@@ -8701,7 +8701,6 @@ packages:
puppeteer@24.10.0:
resolution: {integrity: sha512-Oua9VkGpj0S2psYu5e6mCer6W9AU9POEQh22wRgSXnLXASGH+MwLUVWgLCLeP9QPHHcJ7tySUlg4Sa9OJmaLpw==}
engines: {node: '>=18'}
- deprecated: < 24.15.0 is no longer supported
hasBin: true
pure-rand@6.1.0:
@@ -17122,25 +17121,25 @@ snapshots:
electron-to-chromium@1.5.165: {}
- embla-carousel-autoplay@8.5.2(embla-carousel@8.5.2):
+ embla-carousel-autoplay@9.0.0-rc01(embla-carousel@9.0.0-rc01):
dependencies:
- embla-carousel: 8.5.2
+ embla-carousel: 9.0.0-rc01
- embla-carousel-fade@8.5.2(embla-carousel@8.5.2):
+ embla-carousel-fade@9.0.0-rc01(embla-carousel@9.0.0-rc01):
dependencies:
- embla-carousel: 8.5.2
+ embla-carousel: 9.0.0-rc01
- embla-carousel-react@8.5.2(react@19.1.5):
+ embla-carousel-react@9.0.0-rc01(react@19.1.5):
dependencies:
- embla-carousel: 8.5.2
- embla-carousel-reactive-utils: 8.5.2(embla-carousel@8.5.2)
+ embla-carousel: 9.0.0-rc01
+ embla-carousel-reactive-utils: 9.0.0-rc01(embla-carousel@9.0.0-rc01)
react: 19.1.5
- embla-carousel-reactive-utils@8.5.2(embla-carousel@8.5.2):
+ embla-carousel-reactive-utils@9.0.0-rc01(embla-carousel@9.0.0-rc01):
dependencies:
- embla-carousel: 8.5.2
+ embla-carousel: 9.0.0-rc01
- embla-carousel@8.5.2: {}
+ embla-carousel@9.0.0-rc01: {}
emittery@0.13.1: {}
@@ -17369,8 +17368,8 @@ snapshots:
'@typescript-eslint/parser': 8.28.0(eslint@8.57.1)(typescript@5.8.3)
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.9.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.28.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1)
- eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.28.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.9.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.28.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
+ eslint-import-resolver-typescript: 3.9.1(eslint-plugin-import@2.31.0)(eslint@8.57.1)
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.28.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
eslint-plugin-react: 7.37.4(eslint@8.57.1)
eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1)
@@ -17412,6 +17411,21 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ eslint-import-resolver-typescript@3.9.1(eslint-plugin-import@2.31.0)(eslint@8.57.1):
+ dependencies:
+ '@nolyfill/is-core-module': 1.0.39
+ debug: 4.4.1
+ eslint: 8.57.1
+ get-tsconfig: 4.10.0
+ is-bun-module: 1.3.0
+ rspack-resolver: 1.2.2
+ stable-hash: 0.0.5
+ tinyglobby: 0.2.14
+ optionalDependencies:
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.28.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)
+ transitivePeerDependencies:
+ - supports-color
+
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.28.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.9.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.28.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
dependencies:
debug: 3.2.7
@@ -17462,6 +17476,35 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
+ eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.28.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1):
+ dependencies:
+ '@rtsao/scc': 1.1.0
+ array-includes: 3.1.8
+ array.prototype.findlastindex: 1.2.6
+ array.prototype.flat: 1.3.3
+ array.prototype.flatmap: 1.3.3
+ debug: 3.2.7
+ doctrine: 2.1.0
+ eslint: 8.57.1
+ eslint-import-resolver-node: 0.3.9
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.28.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.9.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.28.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
+ hasown: 2.0.2
+ is-core-module: 2.16.1
+ is-glob: 4.0.3
+ minimatch: 3.1.2
+ object.fromentries: 2.0.8
+ object.groupby: 1.0.3
+ object.values: 1.2.1
+ semver: 6.3.1
+ string.prototype.trimend: 1.0.9
+ tsconfig-paths: 3.15.0
+ optionalDependencies:
+ '@typescript-eslint/parser': 8.28.0(eslint@8.57.1)(typescript@5.8.3)
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
+
eslint-plugin-jest-dom@5.5.0(eslint@8.57.1):
dependencies:
'@babel/runtime': 7.26.7
From f5330c7248b2e3a32b2bfbb8e3bc6c11742a5d27 Mon Sep 17 00:00:00 2001
From: Jorge Moya
Date: Wed, 11 Feb 2026 13:34:33 -0600
Subject: [PATCH 11/17] feat(core): add canonical URLs and hreflang alternates
for SEO (#2856)
* feat(core): add canonical URLs and hreflang alternates for SEO
* feat(core): add canonical URLs to additional pages
Add canonical meta tags to gift certificates, contact, public wishlist,
and compare pages. Update changeset with migration steps for all pages.
Co-Authored-By: Claude Opus 4.5
* fix(core): resolve eslint errors in canonical utility
- Add JSDoc param and returns type annotations
- Replace for...of loop with reduce for array iteration
Co-Authored-By: Claude Opus 4.5
* fix: fetch vanity url
* chore: update changeset
* fix: use URL
---------
Co-authored-by: Claude Opus 4.5
---
.changeset/new-onions-flash.md | 200 ++++++++++++++++++
.../(faceted)/brand/[slug]/page-data.ts | 1 +
.../(default)/(faceted)/brand/[slug]/page.tsx | 4 +-
.../(faceted)/category/[slug]/page.tsx | 9 +-
.../(default)/blog/[blogId]/page-data.ts | 1 +
.../[locale]/(default)/blog/[blogId]/page.tsx | 6 +-
core/app/[locale]/(default)/blog/page.tsx | 2 +
core/app/[locale]/(default)/compare/page.tsx | 2 +
.../gift-certificates/balance/page.tsx | 2 +
.../(default)/gift-certificates/page.tsx | 2 +
.../gift-certificates/purchase/page.tsx | 13 ++
core/app/[locale]/(default)/page.tsx | 10 +
.../(default)/product/[slug]/page-data.ts | 1 +
.../(default)/product/[slug]/page.tsx | 4 +-
.../(default)/webpages/[id]/contact/page.tsx | 4 +-
.../(default)/webpages/[id]/normal/page.tsx | 7 +-
.../(default)/wishlist/[token]/page.tsx | 2 +
core/app/[locale]/layout.tsx | 6 +
core/lib/seo/canonical.ts | 99 +++++++++
19 files changed, 369 insertions(+), 6 deletions(-)
create mode 100644 .changeset/new-onions-flash.md
create mode 100644 core/lib/seo/canonical.ts
diff --git a/.changeset/new-onions-flash.md b/.changeset/new-onions-flash.md
new file mode 100644
index 000000000..7bc9afcce
--- /dev/null
+++ b/.changeset/new-onions-flash.md
@@ -0,0 +1,200 @@
+---
+"@bigcommerce/catalyst-core": patch
+---
+
+Add canonical URLs and hreflang alternates for SEO. Pages now set `alternates.canonical` and `alternates.languages` in `generateMetadata` via the new `getMetadataAlternates` helper in `core/lib/seo/canonical.ts`. The helper fetches the vanity URL via GraphQL (`site.settings.url.vanityUrl`) and is cached per request. The default locale uses no path prefix; other locales use `/{locale}/path`. The root locale layout sets `metadataBase` to the configured vanity URL so canonical URLs resolve correctly.
+
+## Migration steps
+
+### Step 1: Root layout metadata base
+
+The root locale layout now sets `metadataBase` from the vanity URL fetched via GraphQL. This is already included in the `RootLayoutMetadataQuery`.
+
+Update `core/app/[locale]/layout.tsx`:
+
+```diff
++ const vanityUrl = data.site.settings?.url.vanityUrl;
++
+ return {
++ metadataBase: vanityUrl ? new URL(vanityUrl) : undefined,
+ title: {
+```
+
+### Step 2: GraphQL fragment updates
+
+Add the `path` field to brand, blog post, and product queries so metadata can build canonical URLs.
+
+Update `core/app/[locale]/(default)/(faceted)/brand/[slug]/page-data.ts`:
+
+```diff
+ site {
+ brand(entityId: $entityId) {
+ name
++ path
+ seo {
+```
+
+Update `core/app/[locale]/(default)/blog/[blogId]/page-data.ts`:
+
+```diff
+ author
+ htmlBody
+ name
++ path
+ publishedDate {
+```
+
+Update `core/app/[locale]/(default)/product/[slug]/page-data.ts` (in the metadata query):
+
+```diff
+ site {
+ product(entityId: $entityId) {
+ name
++ path
+ defaultImage {
+```
+
+### Step 3: Page metadata alternates
+
+Add the `getMetadataAlternates` import and set `alternates` in `generateMetadata` for each page. The function is async and must be awaited. Ensure `core/lib/seo/canonical.ts` exists (it is included in this release).
+
+Update `core/app/[locale]/(default)/page.tsx` (home):
+
+```diff
++ import { Metadata } from 'next';
+ import { getFormatter, getTranslations, setRequestLocale } from 'next-intl/server';
+ ...
++ import { getMetadataAlternates } from '~/lib/seo/canonical';
+ ...
++ export async function generateMetadata({ params }: Props): Promise {
++ const { locale } = await params;
++ return {
++ alternates: await getMetadataAlternates({ path: '/', locale }),
++ };
++ }
++
+ export default async function Home({ params }: Props) {
+```
+
+For entity pages (product, category, brand, blog, blog post, webpage), add the import and include `alternates` in the existing `generateMetadata` return value using the entity `path` (or breadcrumb-derived path for category and webpage). Example for a brand page:
+
+```diff
++ import { getMetadataAlternates } from '~/lib/seo/canonical';
+ ...
+ export async function generateMetadata(props: Props): Promise {
+- const { slug } = await props.params;
++ const { slug, locale } = await props.params;
+ ...
+ return {
+ title: pageTitle || brand.name,
+ description: metaDescription,
+ keywords: metaKeywords ? metaKeywords.split(',') : null,
++ alternates: await getMetadataAlternates({ path: brand.path, locale }),
+ };
+ }
+```
+
+### Step 4: Gift certificates pages
+
+Update `core/app/[locale]/(default)/gift-certificates/page.tsx`:
+
+```diff
++ import { getMetadataAlternates } from '~/lib/seo/canonical';
+ ...
+ export async function generateMetadata({ params }: Props): Promise {
+ const { locale } = await params;
+ const t = await getTranslations({ locale, namespace: 'GiftCertificates' });
+
+ return {
+ title: t('title') || 'Gift certificates',
++ alternates: await getMetadataAlternates({ path: '/gift-certificates', locale }),
+ };
+ }
+```
+
+Update `core/app/[locale]/(default)/gift-certificates/balance/page.tsx`:
+
+```diff
++ import { getMetadataAlternates } from '~/lib/seo/canonical';
+ ...
+ return {
+ title: t('title') || 'Gift certificates - Check balance',
++ alternates: await getMetadataAlternates({ path: '/gift-certificates/balance', locale }),
+ };
+```
+
+Add `generateMetadata` to `core/app/[locale]/(default)/gift-certificates/purchase/page.tsx`:
+
+```diff
++ import { Metadata } from 'next';
+ import { getFormatter, getTranslations } from 'next-intl/server';
+ ...
++ import { getMetadataAlternates } from '~/lib/seo/canonical';
+ ...
++ export async function generateMetadata({ params }: Props): Promise {
++ const { locale } = await params;
++ const t = await getTranslations({ locale, namespace: 'GiftCertificates' });
++
++ return {
++ title: t('Purchase.title'),
++ alternates: await getMetadataAlternates({ path: '/gift-certificates/purchase', locale }),
++ };
++ }
+```
+
+### Step 5: Contact page
+
+Update `core/app/[locale]/(default)/webpages/[id]/contact/page.tsx`:
+
+```diff
++ import { getMetadataAlternates } from '~/lib/seo/canonical';
+ ...
+ export async function generateMetadata({ params }: Props): Promise {
+- const { id } = await params;
++ const { id, locale } = await params;
+ const webpage = await getWebPage(id);
+ const { pageTitle, metaDescription, metaKeywords } = webpage.seo;
+
+ return {
+ title: pageTitle || webpage.title,
+ description: metaDescription,
+ keywords: metaKeywords ? metaKeywords.split(',') : null,
++ alternates: await getMetadataAlternates({ path: webpage.path, locale }),
+ };
+ }
+```
+
+### Step 6: Public wishlist page
+
+Update `core/app/[locale]/(default)/wishlist/[token]/page.tsx`:
+
+```diff
++ import { getMetadataAlternates } from '~/lib/seo/canonical';
+ ...
+ export async function generateMetadata({ params, searchParams }: Props): Promise {
+ const { locale, token } = await params;
+ ...
+ return {
+ title: wishlist?.name ?? t('title'),
++ alternates: await getMetadataAlternates({ path: `/wishlist/${token}`, locale }),
+ };
+ }
+```
+
+### Step 7: Compare page
+
+Update `core/app/[locale]/(default)/compare/page.tsx`:
+
+```diff
++ import { getMetadataAlternates } from '~/lib/seo/canonical';
+ ...
+ export async function generateMetadata({ params }: Props): Promise {
+ const { locale } = await params;
+ const t = await getTranslations({ locale, namespace: 'Compare' });
+
+ return {
+ title: t('title'),
++ alternates: await getMetadataAlternates({ path: '/compare', locale }),
+ };
+ }
+```
diff --git a/core/app/[locale]/(default)/(faceted)/brand/[slug]/page-data.ts b/core/app/[locale]/(default)/(faceted)/brand/[slug]/page-data.ts
index 918affded..9bb605d21 100644
--- a/core/app/[locale]/(default)/(faceted)/brand/[slug]/page-data.ts
+++ b/core/app/[locale]/(default)/(faceted)/brand/[slug]/page-data.ts
@@ -9,6 +9,7 @@ const BrandPageQuery = graphql(`
site {
brand(entityId: $entityId) {
name
+ path
seo {
pageTitle
metaDescription
diff --git a/core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx b/core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx
index 407892f55..163419493 100644
--- a/core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx
+++ b/core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx
@@ -13,6 +13,7 @@ import { facetsTransformer } from '~/data-transformers/facets-transformer';
import { pageInfoTransformer } from '~/data-transformers/page-info-transformer';
import { productCardTransformer } from '~/data-transformers/product-card-transformer';
import { getPreferredCurrencyCode } from '~/lib/currency';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { MAX_COMPARE_LIMIT } from '../../../compare/page-data';
import { getCompareProducts as getCompareProductsData } from '../../fetch-compare-products';
@@ -67,7 +68,7 @@ interface Props {
}
export async function generateMetadata(props: Props): Promise {
- const { slug } = await props.params;
+ const { slug, locale } = await props.params;
const customerAccessToken = await getSessionCustomerAccessToken();
const brandId = Number(slug);
@@ -84,6 +85,7 @@ export async function generateMetadata(props: Props): Promise {
title: pageTitle || brand.name,
description: metaDescription,
keywords: metaKeywords ? metaKeywords.split(',') : null,
+ alternates: await getMetadataAlternates({ path: brand.path, locale }),
};
}
diff --git a/core/app/[locale]/(default)/(faceted)/category/[slug]/page.tsx b/core/app/[locale]/(default)/(faceted)/category/[slug]/page.tsx
index e09abcf7b..3471282dd 100644
--- a/core/app/[locale]/(default)/(faceted)/category/[slug]/page.tsx
+++ b/core/app/[locale]/(default)/(faceted)/category/[slug]/page.tsx
@@ -14,6 +14,7 @@ import { facetsTransformer } from '~/data-transformers/facets-transformer';
import { pageInfoTransformer } from '~/data-transformers/page-info-transformer';
import { productCardTransformer } from '~/data-transformers/product-card-transformer';
import { getPreferredCurrencyCode } from '~/lib/currency';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { MAX_COMPARE_LIMIT } from '../../../compare/page-data';
import { getCompareProducts } from '../../fetch-compare-products';
@@ -69,7 +70,7 @@ interface Props {
}
export async function generateMetadata(props: Props): Promise {
- const { slug } = await props.params;
+ const { slug, locale } = await props.params;
const customerAccessToken = await getSessionCustomerAccessToken();
const categoryId = Number(slug);
@@ -82,10 +83,16 @@ export async function generateMetadata(props: Props): Promise {
const { pageTitle, metaDescription, metaKeywords } = category.seo;
+ const breadcrumbs = removeEdgesAndNodes(category.breadcrumbs);
+ const categoryPath = breadcrumbs[breadcrumbs.length - 1]?.path;
+
return {
title: pageTitle || category.name,
description: metaDescription,
keywords: metaKeywords ? metaKeywords.split(',') : null,
+ ...(categoryPath && {
+ alternates: await getMetadataAlternates({ path: categoryPath, locale }),
+ }),
};
}
diff --git a/core/app/[locale]/(default)/blog/[blogId]/page-data.ts b/core/app/[locale]/(default)/blog/[blogId]/page-data.ts
index ec480d77b..472c44059 100644
--- a/core/app/[locale]/(default)/blog/[blogId]/page-data.ts
+++ b/core/app/[locale]/(default)/blog/[blogId]/page-data.ts
@@ -15,6 +15,7 @@ const BlogPageQuery = graphql(`
author
htmlBody
name
+ path
publishedDate {
utc
}
diff --git a/core/app/[locale]/(default)/blog/[blogId]/page.tsx b/core/app/[locale]/(default)/blog/[blogId]/page.tsx
index e6bda68e8..35ba4ffa9 100644
--- a/core/app/[locale]/(default)/blog/[blogId]/page.tsx
+++ b/core/app/[locale]/(default)/blog/[blogId]/page.tsx
@@ -5,6 +5,7 @@ import { cache } from 'react';
import { BlogPostContent, BlogPostContentBlogPost } from '@/vibes/soul/sections/blog-post-content';
import { Breadcrumb } from '@/vibes/soul/sections/breadcrumbs';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { getBlogPageData } from './page-data';
@@ -18,7 +19,7 @@ interface Props {
}
export async function generateMetadata({ params }: Props): Promise {
- const { blogId } = await params;
+ const { blogId, locale } = await params;
const variables = cachedBlogPageDataVariables(blogId);
@@ -35,6 +36,9 @@ export async function generateMetadata({ params }: Props): Promise {
title: pageTitle || blogPost.name,
description: metaDescription,
keywords: metaKeywords ? metaKeywords.split(',') : null,
+ ...(blogPost.path && {
+ alternates: await getMetadataAlternates({ path: blogPost.path, locale }),
+ }),
};
}
diff --git a/core/app/[locale]/(default)/blog/page.tsx b/core/app/[locale]/(default)/blog/page.tsx
index b0756183f..e960967c5 100644
--- a/core/app/[locale]/(default)/blog/page.tsx
+++ b/core/app/[locale]/(default)/blog/page.tsx
@@ -7,6 +7,7 @@ import { createSearchParamsCache, parseAsInteger, parseAsString } from 'nuqs/ser
import { Streamable } from '@/vibes/soul/lib/streamable';
import { FeaturedBlogPostList } from '@/vibes/soul/sections/featured-blog-post-list';
import { defaultPageInfo, pageInfoTransformer } from '~/data-transformers/page-info-transformer';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { getBlog, getBlogPosts } from './page-data';
@@ -36,6 +37,7 @@ export async function generateMetadata({ params }: Props): Promise {
blog?.description && blog.description.length > 150
? `${blog.description.substring(0, 150)}...`
: blog?.description,
+ ...(blog?.path && { alternates: await getMetadataAlternates({ path: blog.path, locale }) }),
};
}
diff --git a/core/app/[locale]/(default)/compare/page.tsx b/core/app/[locale]/(default)/compare/page.tsx
index 79ed057c0..ac851ddb1 100644
--- a/core/app/[locale]/(default)/compare/page.tsx
+++ b/core/app/[locale]/(default)/compare/page.tsx
@@ -8,6 +8,7 @@ import { CompareSection } from '@/vibes/soul/sections/compare-section';
import { getSessionCustomerAccessToken } from '~/auth';
import { pricesTransformer } from '~/data-transformers/prices-transformer';
import { getPreferredCurrencyCode } from '~/lib/currency';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { addToCart } from './_actions/add-to-cart';
import { CompareAnalyticsProvider } from './_components/compare-analytics-provider';
@@ -44,6 +45,7 @@ export async function generateMetadata({ params }: Props): Promise {
return {
title: t('title'),
+ alternates: await getMetadataAlternates({ path: '/compare', locale }),
};
}
diff --git a/core/app/[locale]/(default)/gift-certificates/balance/page.tsx b/core/app/[locale]/(default)/gift-certificates/balance/page.tsx
index d56106a6e..0320e48ac 100644
--- a/core/app/[locale]/(default)/gift-certificates/balance/page.tsx
+++ b/core/app/[locale]/(default)/gift-certificates/balance/page.tsx
@@ -4,6 +4,7 @@ import { getTranslations, setRequestLocale } from 'next-intl/server';
import { GiftCertificateCheckBalanceSection } from '@/vibes/soul/sections/gift-certificate-balance-section';
import { redirect } from '~/i18n/routing';
import { getPreferredCurrencyCode } from '~/lib/currency';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { getGiftCertificatesData } from '../page-data';
@@ -20,6 +21,7 @@ export async function generateMetadata({ params }: Props): Promise {
return {
title: t('title') || 'Gift certificates - Check balance',
+ alternates: await getMetadataAlternates({ path: '/gift-certificates/balance', locale }),
};
}
diff --git a/core/app/[locale]/(default)/gift-certificates/page.tsx b/core/app/[locale]/(default)/gift-certificates/page.tsx
index e0117c53f..5c50984fb 100644
--- a/core/app/[locale]/(default)/gift-certificates/page.tsx
+++ b/core/app/[locale]/(default)/gift-certificates/page.tsx
@@ -4,6 +4,7 @@ import { getFormatter, getTranslations, setRequestLocale } from 'next-intl/serve
import { GiftCertificatesSection } from '@/vibes/soul/sections/gift-certificates-section';
import { redirect } from '~/i18n/routing';
import { getPreferredCurrencyCode } from '~/lib/currency';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { getGiftCertificatesData } from './page-data';
@@ -18,6 +19,7 @@ export async function generateMetadata({ params }: Props): Promise {
return {
title: t('title') || 'Gift certificates',
+ alternates: await getMetadataAlternates({ path: '/gift-certificates', locale }),
};
}
diff --git a/core/app/[locale]/(default)/gift-certificates/purchase/page.tsx b/core/app/[locale]/(default)/gift-certificates/purchase/page.tsx
index 74f60684f..29e4158c7 100644
--- a/core/app/[locale]/(default)/gift-certificates/purchase/page.tsx
+++ b/core/app/[locale]/(default)/gift-certificates/purchase/page.tsx
@@ -1,4 +1,5 @@
import { ResultOf } from 'gql.tada';
+import { Metadata } from 'next';
import { getFormatter, getTranslations } from 'next-intl/server';
import { Field, FieldGroup } from '@/vibes/soul/form/dynamic-form/schema';
@@ -7,6 +8,7 @@ import { GiftCertificateSettingsFragment } from '~/app/[locale]/(default)/gift-c
import { ExistingResultType } from '~/client/util';
import { redirect } from '~/i18n/routing';
import { getPreferredCurrencyCode } from '~/lib/currency';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { addGiftCertificateToCart } from './_actions/add-to-cart';
import { getGiftCertificatePurchaseData } from './page-data';
@@ -15,6 +17,17 @@ interface Props {
params: Promise<{ locale: string }>;
}
+export async function generateMetadata({ params }: Props): Promise {
+ const { locale } = await params;
+
+ const t = await getTranslations({ locale, namespace: 'GiftCertificates' });
+
+ return {
+ title: t('Purchase.title'),
+ alternates: await getMetadataAlternates({ path: '/gift-certificates/purchase', locale }),
+ };
+}
+
function getFields(
giftCertificateSettings: ResultOf,
expiresAt: string | undefined,
diff --git a/core/app/[locale]/(default)/page.tsx b/core/app/[locale]/(default)/page.tsx
index 0e34bc75a..77cf4db61 100644
--- a/core/app/[locale]/(default)/page.tsx
+++ b/core/app/[locale]/(default)/page.tsx
@@ -1,4 +1,5 @@
import { removeEdgesAndNodes } from '@bigcommerce/catalyst-client';
+import { Metadata } from 'next';
import { getFormatter, getTranslations, setRequestLocale } from 'next-intl/server';
import { Stream, Streamable } from '@/vibes/soul/lib/streamable';
@@ -8,6 +9,7 @@ import { getSessionCustomerAccessToken } from '~/auth';
import { Subscribe } from '~/components/subscribe';
import { productCardTransformer } from '~/data-transformers/product-card-transformer';
import { getPreferredCurrencyCode } from '~/lib/currency';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { Slideshow } from './_components/slideshow';
import { getPageData } from './page-data';
@@ -16,6 +18,14 @@ interface Props {
params: Promise<{ locale: string }>;
}
+export async function generateMetadata({ params }: Props): Promise {
+ const { locale } = await params;
+
+ return {
+ alternates: await getMetadataAlternates({ path: '/', locale }),
+ };
+}
+
export default async function Home({ params }: Props) {
const { locale } = await params;
diff --git a/core/app/[locale]/(default)/product/[slug]/page-data.ts b/core/app/[locale]/(default)/product/[slug]/page-data.ts
index 0f7fccc2c..0e1931e18 100644
--- a/core/app/[locale]/(default)/product/[slug]/page-data.ts
+++ b/core/app/[locale]/(default)/product/[slug]/page-data.ts
@@ -138,6 +138,7 @@ const ProductPageMetadataQuery = graphql(`
site {
product(entityId: $entityId) {
name
+ path
defaultImage {
altText
url: urlTemplate(lossy: true)
diff --git a/core/app/[locale]/(default)/product/[slug]/page.tsx b/core/app/[locale]/(default)/product/[slug]/page.tsx
index b43267904..e29496cd4 100644
--- a/core/app/[locale]/(default)/product/[slug]/page.tsx
+++ b/core/app/[locale]/(default)/product/[slug]/page.tsx
@@ -12,6 +12,7 @@ import { pricesTransformer } from '~/data-transformers/prices-transformer';
import { productCardTransformer } from '~/data-transformers/product-card-transformer';
import { productOptionsTransformer } from '~/data-transformers/product-options-transformer';
import { getPreferredCurrencyCode } from '~/lib/currency';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { addToCart } from './_actions/add-to-cart';
import { getMoreProductImages } from './_actions/get-more-images';
@@ -37,7 +38,7 @@ interface Props {
}
export async function generateMetadata({ params }: Props): Promise {
- const { slug } = await params;
+ const { slug, locale } = await params;
const customerAccessToken = await getSessionCustomerAccessToken();
const productId = Number(slug);
@@ -55,6 +56,7 @@ export async function generateMetadata({ params }: Props): Promise {
title: pageTitle || product.name,
description: metaDescription || `${product.plainTextDescription.slice(0, 150)}...`,
keywords: metaKeywords ? metaKeywords.split(',') : null,
+ alternates: await getMetadataAlternates({ path: product.path, locale }),
openGraph: url
? {
images: [
diff --git a/core/app/[locale]/(default)/webpages/[id]/contact/page.tsx b/core/app/[locale]/(default)/webpages/[id]/contact/page.tsx
index 144381f12..e053978db 100644
--- a/core/app/[locale]/(default)/webpages/[id]/contact/page.tsx
+++ b/core/app/[locale]/(default)/webpages/[id]/contact/page.tsx
@@ -12,6 +12,7 @@ import {
breadcrumbsTransformer,
truncateBreadcrumbs,
} from '~/data-transformers/breadcrumbs-transformer';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { WebPage, WebPageContent } from '../_components/web-page';
@@ -153,7 +154,7 @@ async function getContactFields(id: string) {
}
export async function generateMetadata({ params }: Props): Promise {
- const { id } = await params;
+ const { id, locale } = await params;
const webpage = await getWebPage(id);
const { pageTitle, metaDescription, metaKeywords } = webpage.seo;
@@ -161,6 +162,7 @@ export async function generateMetadata({ params }: Props): Promise {
title: pageTitle || webpage.title,
description: metaDescription,
keywords: metaKeywords ? metaKeywords.split(',') : null,
+ alternates: await getMetadataAlternates({ path: webpage.path, locale }),
};
}
diff --git a/core/app/[locale]/(default)/webpages/[id]/normal/page.tsx b/core/app/[locale]/(default)/webpages/[id]/normal/page.tsx
index a92303044..6406c381d 100644
--- a/core/app/[locale]/(default)/webpages/[id]/normal/page.tsx
+++ b/core/app/[locale]/(default)/webpages/[id]/normal/page.tsx
@@ -9,6 +9,7 @@ import {
breadcrumbsTransformer,
truncateBreadcrumbs,
} from '~/data-transformers/breadcrumbs-transformer';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { WebPageContent, WebPage as WebPageData } from '../_components/web-page';
@@ -57,14 +58,18 @@ async function getWebPageBreadcrumbs(id: string): Promise {
}
export async function generateMetadata({ params }: Props): Promise {
- const { id } = await params;
+ const { id, locale } = await params;
const webpage = await getWebPage(id);
const { pageTitle, metaDescription, metaKeywords } = webpage.seo;
+ // Get the path from the last breadcrumb
+ const pagePath = webpage.breadcrumbs[webpage.breadcrumbs.length - 1]?.href;
+
return {
title: pageTitle || webpage.title,
description: metaDescription,
keywords: metaKeywords ? metaKeywords.split(',') : null,
+ ...(pagePath && { alternates: await getMetadataAlternates({ path: pagePath, locale }) }),
};
}
diff --git a/core/app/[locale]/(default)/wishlist/[token]/page.tsx b/core/app/[locale]/(default)/wishlist/[token]/page.tsx
index 0ee9fc40b..e6fe52378 100644
--- a/core/app/[locale]/(default)/wishlist/[token]/page.tsx
+++ b/core/app/[locale]/(default)/wishlist/[token]/page.tsx
@@ -19,6 +19,7 @@ import {
} from '~/components/wishlist/share-button';
import { defaultPageInfo, pageInfoTransformer } from '~/data-transformers/page-info-transformer';
import { publicWishlistDetailsTransformer } from '~/data-transformers/wishlists-transformer';
+import { getMetadataAlternates } from '~/lib/seo/canonical';
import { isMobileUser } from '~/lib/user-agent';
import { getPublicWishlist } from './page-data';
@@ -73,6 +74,7 @@ export async function generateMetadata({ params, searchParams }: Props): Promise
return {
title: wishlist?.name ?? t('title'),
+ alternates: await getMetadataAlternates({ path: `/wishlist/${token}`, locale }),
};
}
diff --git a/core/app/[locale]/layout.tsx b/core/app/[locale]/layout.tsx
index 14fc07ce5..ae7642bd3 100644
--- a/core/app/[locale]/layout.tsx
+++ b/core/app/[locale]/layout.tsx
@@ -30,6 +30,9 @@ const RootLayoutMetadataQuery = graphql(
query RootLayoutMetadataQuery {
site {
settings {
+ url {
+ vanityUrl
+ }
privacy {
cookieConsentEnabled
privacyPolicyUrl
@@ -68,7 +71,10 @@ export async function generateMetadata(): Promise {
const { pageTitle, metaDescription, metaKeywords } = data.site.settings?.seo || {};
+ const vanityUrl = data.site.settings?.url.vanityUrl;
+
return {
+ metadataBase: vanityUrl ? new URL(vanityUrl) : undefined,
title: {
template: `%s - ${storeName}`,
default: pageTitle || storeName,
diff --git a/core/lib/seo/canonical.ts b/core/lib/seo/canonical.ts
new file mode 100644
index 000000000..03f9cac3f
--- /dev/null
+++ b/core/lib/seo/canonical.ts
@@ -0,0 +1,99 @@
+import { cache } from 'react';
+
+import { client } from '~/client';
+import { graphql } from '~/client/graphql';
+import { revalidate } from '~/client/revalidate-target';
+import { defaultLocale, locales } from '~/i18n/locales';
+
+interface CanonicalUrlOptions {
+ /**
+ * The path from BigCommerce (e.g., product.path, category.path)
+ * or a manually constructed path for static pages (e.g., '/')
+ */
+ path: string;
+ /**
+ * Current locale from params
+ */
+ locale: string;
+ /**
+ * Whether to include hreflang alternates for all locales
+ * @default true
+ */
+ includeAlternates?: boolean;
+}
+
+/**
+ * Generates metadata alternates object for Next.js Metadata API
+ *
+ * Rules:
+ * - Default locale: no prefix (e.g., https://example.com/product/)
+ * - Other locales: with prefix (e.g., https://example.com/fr/product/)
+ * - Respects TRAILING_SLASH environment variable
+ *
+ * @param {CanonicalUrlOptions} options - The options for generating canonical URLs
+ * @returns {object} The metadata alternates object with canonical URL and optional language alternates
+ */
+const VanityUrlQuery = graphql(`
+ query VanityUrlQuery {
+ site {
+ settings {
+ url {
+ vanityUrl
+ }
+ }
+ }
+ }
+`);
+
+const getVanityUrl = cache(async () => {
+ const { data } = await client.fetch({
+ document: VanityUrlQuery,
+ fetchOptions: { next: { revalidate } },
+ });
+
+ const vanityUrl = data.site.settings?.url.vanityUrl;
+
+ if (!vanityUrl) {
+ throw new Error('Vanity URL not found in site settings');
+ }
+
+ return vanityUrl;
+});
+
+export async function getMetadataAlternates(options: CanonicalUrlOptions) {
+ const { path, locale, includeAlternates = true } = options;
+
+ const baseUrl = await getVanityUrl();
+
+ const canonical = buildLocalizedUrl(baseUrl, path, locale);
+
+ if (!includeAlternates) {
+ return { canonical };
+ }
+
+ const languages = locales.reduce>((acc, loc) => {
+ acc[loc] = buildLocalizedUrl(baseUrl, path, loc);
+
+ return acc;
+ }, {});
+
+ languages['x-default'] = buildLocalizedUrl(baseUrl, path, defaultLocale);
+
+ return { canonical, languages };
+}
+
+function buildLocalizedUrl(baseUrl: string, pathname: string, locale: string): string {
+ const trailingSlash = process.env.TRAILING_SLASH !== 'false';
+
+ const url = new URL(pathname, baseUrl);
+
+ url.pathname = locale === defaultLocale ? url.pathname : `/${locale}${url.pathname}`;
+
+ if (trailingSlash && !url.pathname.endsWith('/')) {
+ url.pathname += '/';
+ } else if (!trailingSlash && url.pathname.endsWith('/') && url.pathname !== '/') {
+ url.pathname = url.pathname.slice(0, -1);
+ }
+
+ return url.href;
+}
From 18cfdc8ca018c33ea49b462ecb6f055a153cd4ab Mon Sep 17 00:00:00 2001
From: Tharaa <36555311+Tharaae@users.noreply.github.com>
Date: Thu, 12 Feb 2026 07:06:33 +1100
Subject: [PATCH 12/17] feat: Remove caching on fetching product inventory data
(#2801)
* feat: Remove caching on fetching product inventory data
* feat: Remove caching on fetching product inventory data - Apply comments
---
.changeset/eager-nails-bake.md | 10 ++++
.../(default)/product/[slug]/page-data.ts | 56 ++++++++++++++-----
.../(default)/product/[slug]/page.tsx | 35 ++++++++----
3 files changed, 77 insertions(+), 24 deletions(-)
create mode 100644 .changeset/eager-nails-bake.md
diff --git a/.changeset/eager-nails-bake.md b/.changeset/eager-nails-bake.md
new file mode 100644
index 000000000..cce2f5369
--- /dev/null
+++ b/.changeset/eager-nails-bake.md
@@ -0,0 +1,10 @@
+---
+"@bigcommerce/catalyst-core": minor
+---
+
+Fetch product inventory data with a separate GQL query with no caching
+
+## Migration
+The files to be rebased for this change to be applied are:
+- core/app/[locale]/(default)/product/[slug]/page-data.ts
+- core/app/[locale]/(default)/product/[slug]/page.tsx
\ No newline at end of file
diff --git a/core/app/[locale]/(default)/product/[slug]/page-data.ts b/core/app/[locale]/(default)/product/[slug]/page-data.ts
index 0e1931e18..02a829373 100644
--- a/core/app/[locale]/(default)/product/[slug]/page-data.ts
+++ b/core/app/[locale]/(default)/product/[slug]/page-data.ts
@@ -211,7 +211,7 @@ export const getProduct = cache(async (entityId: number, customerAccessToken?: s
return data.site;
});
-const StreamableProductVariantBySkuQuery = graphql(`
+const StreamableProductVariantInventoryBySkuQuery = graphql(`
query ProductVariantBySkuQuery($productId: Int!, $sku: String!) {
site {
product(entityId: $productId) {
@@ -247,15 +247,15 @@ const StreamableProductVariantBySkuQuery = graphql(`
}
`);
-type VariantVariables = VariablesOf;
+type VariantInventoryVariables = VariablesOf;
-export const getStreamableProductVariant = cache(
- async (variables: VariantVariables, customerAccessToken?: string) => {
+export const getStreamableProductVariantInventory = cache(
+ async (variables: VariantInventoryVariables, customerAccessToken?: string) => {
const { data } = await client.fetch({
- document: StreamableProductVariantBySkuQuery,
+ document: StreamableProductVariantInventoryBySkuQuery,
variables,
customerAccessToken,
- fetchOptions: customerAccessToken ? { cache: 'no-store' } : { next: { revalidate } },
+ fetchOptions: customerAccessToken ? { cache: 'no-store' } : { next: { revalidate: 60 } },
});
return data.site.product?.variants;
@@ -311,6 +311,36 @@ const StreamableProductQuery = graphql(
minPurchaseQuantity
maxPurchaseQuantity
warranty
+ ...ProductViewedFragment
+ ...ProductSchemaFragment
+ }
+ }
+ }
+ `,
+ [ProductViewedFragment, ProductSchemaFragment],
+);
+
+type Variables = VariablesOf;
+
+export const getStreamableProduct = cache(
+ async (variables: Variables, customerAccessToken?: string) => {
+ const { data } = await client.fetch({
+ document: StreamableProductQuery,
+ variables,
+ customerAccessToken,
+ fetchOptions: customerAccessToken ? { cache: 'no-store' } : { next: { revalidate } },
+ });
+
+ return data.site.product;
+ },
+);
+
+const StreamableProductInventoryQuery = graphql(
+ `
+ query StreamableProductInventoryQuery($entityId: Int!) {
+ site {
+ product(entityId: $entityId) {
+ sku
inventory {
hasVariantInventory
isInStock
@@ -325,25 +355,23 @@ const StreamableProductQuery = graphql(
availabilityV2 {
status
}
- ...ProductViewedFragment
...ProductVariantsInventoryFragment
- ...ProductSchemaFragment
}
}
}
`,
- [ProductViewedFragment, ProductSchemaFragment, ProductVariantsInventoryFragment],
+ [ProductVariantsInventoryFragment],
);
-type Variables = VariablesOf;
+type ProductInventoryVariables = VariablesOf;
-export const getStreamableProduct = cache(
- async (variables: Variables, customerAccessToken?: string) => {
+export const getStreamableProductInventory = cache(
+ async (variables: ProductInventoryVariables, customerAccessToken?: string) => {
const { data } = await client.fetch({
- document: StreamableProductQuery,
+ document: StreamableProductInventoryQuery,
variables,
customerAccessToken,
- fetchOptions: customerAccessToken ? { cache: 'no-store' } : { next: { revalidate } },
+ fetchOptions: customerAccessToken ? { cache: 'no-store' } : { next: { revalidate: 60 } },
});
return data.site.product;
diff --git a/core/app/[locale]/(default)/product/[slug]/page.tsx b/core/app/[locale]/(default)/product/[slug]/page.tsx
index e29496cd4..5f31e4dad 100644
--- a/core/app/[locale]/(default)/product/[slug]/page.tsx
+++ b/core/app/[locale]/(default)/product/[slug]/page.tsx
@@ -29,7 +29,8 @@ import {
getProductPricingAndRelatedProducts,
getStreamableInventorySettingsQuery,
getStreamableProduct,
- getStreamableProductVariant,
+ getStreamableProductInventory,
+ getStreamableProductVariantInventory,
} from './page-data';
interface Props {
@@ -120,8 +121,22 @@ export default async function Product({ params, searchParams }: Props) {
const streamableProductSku = Streamable.from(async () => (await streamableProduct).sku);
- const streamableProductVariant = Streamable.from(async () => {
- const product = await streamableProduct;
+ const streamableProductInventory = Streamable.from(async () => {
+ const variables = {
+ entityId: Number(productId),
+ };
+
+ const product = await getStreamableProductInventory(variables, customerAccessToken);
+
+ if (!product) {
+ return notFound();
+ }
+
+ return product;
+ });
+
+ const streamableProductVariantInventory = Streamable.from(async () => {
+ const product = await streamableProductInventory;
if (!product.inventory.hasVariantInventory) {
return undefined;
@@ -132,7 +147,7 @@ export default async function Product({ params, searchParams }: Props) {
sku: product.sku,
};
- const variants = await getStreamableProductVariant(variables, customerAccessToken);
+ const variants = await getStreamableProductVariantInventory(variables, customerAccessToken);
if (!variants) {
return undefined;
@@ -194,7 +209,7 @@ export default async function Product({ params, searchParams }: Props) {
});
const streameableCtaLabel = Streamable.from(async () => {
- const product = await streamableProduct;
+ const product = await streamableProductInventory;
if (product.availabilityV2.status === 'Unavailable') {
return t('ProductDetails.Submit.unavailable');
@@ -212,7 +227,7 @@ export default async function Product({ params, searchParams }: Props) {
});
const streameableCtaDisabled = Streamable.from(async () => {
- const product = await streamableProduct;
+ const product = await streamableProductInventory;
if (product.availabilityV2.status === 'Unavailable') {
return true;
@@ -259,8 +274,8 @@ export default async function Product({ params, searchParams }: Props) {
const streamableStockDisplayData = Streamable.from(async () => {
const [product, variant, inventorySetting] = await Streamable.all([
- streamableProduct,
- streamableProductVariant,
+ streamableProductInventory,
+ streamableProductVariantInventory,
streamableInventorySettings,
]);
@@ -349,8 +364,8 @@ export default async function Product({ params, searchParams }: Props) {
const streamableBackorderDisplayData = Streamable.from(async () => {
const [product, variant, inventorySetting] = await Streamable.all([
- streamableProduct,
- streamableProductVariant,
+ streamableProductInventory,
+ streamableProductVariantInventory,
streamableInventorySettings,
]);
From 169cbb5719ba49cbe11bcd9fa3de30a01c8edfb9 Mon Sep 17 00:00:00 2001
From: Ivan Shcherbak
Date: Wed, 18 Feb 2026 20:02:28 +0200
Subject: [PATCH 13/17] feat(other): LOCAL-1444 delivery translation (#2886)
Co-authored-by: funivan
---
core/messages/da.json | 126 +++++++++++++++++++++++++++++++++-----
core/messages/de.json | 126 +++++++++++++++++++++++++++++++++-----
core/messages/es-419.json | 124 ++++++++++++++++++++++++++++++++-----
core/messages/es-AR.json | 124 ++++++++++++++++++++++++++++++++-----
core/messages/es-CL.json | 124 ++++++++++++++++++++++++++++++++-----
core/messages/es-CO.json | 124 ++++++++++++++++++++++++++++++++-----
core/messages/es-LA.json | 124 ++++++++++++++++++++++++++++++++-----
core/messages/es-MX.json | 124 ++++++++++++++++++++++++++++++++-----
core/messages/es-PE.json | 124 ++++++++++++++++++++++++++++++++-----
core/messages/es.json | 126 +++++++++++++++++++++++++++++++++-----
core/messages/fr.json | 126 +++++++++++++++++++++++++++++++++-----
core/messages/it.json | 126 +++++++++++++++++++++++++++++++++-----
core/messages/ja.json | 124 ++++++++++++++++++++++++++++++++-----
core/messages/nl.json | 126 +++++++++++++++++++++++++++++++++-----
core/messages/no.json | 126 +++++++++++++++++++++++++++++++++-----
core/messages/pl.json | 114 ++++++++++++++++++++++++++++++----
core/messages/pt-BR.json | 114 ++++++++++++++++++++++++++++++----
core/messages/pt.json | 114 ++++++++++++++++++++++++++++++----
core/messages/sv.json | 126 +++++++++++++++++++++++++++++++++-----
19 files changed, 2045 insertions(+), 297 deletions(-)
diff --git a/core/messages/da.json b/core/messages/da.json
index 33755c849..0f571c362 100644
--- a/core/messages/da.json
+++ b/core/messages/da.json
@@ -43,7 +43,17 @@
"newPassword": "Den nye adgangskode",
"confirmPassword": "Bekræft adgangskode",
"passwordUpdated": "Adgangskoden er blevet opdateret.",
- "somethingWentWrong": "Noget gik galt. Prøv igen senere."
+ "somethingWentWrong": "Noget gik galt. Prøv igen senere.",
+ "FieldErrors": {
+ "passwordRequired": "Adgangskode er påkrævet",
+ "passwordTooSmall": "Adgangskoden skal være på mindst {minLength, plural, =1 {1 character} other {# characters}}",
+ "passwordLowercaseRequired": "Adgangskoden skal indeholde mindst ét lille bogstav",
+ "passwordUppercaseRequired": "Adgangskoden skal indeholde mindst ét stort bogstav",
+ "passwordNumberRequired": "Adgangskoden skal indeholde mindst {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Adgangskoden skal indeholde mindst ét specialtegn",
+ "passwordsMustMatch": "Adgangskoderne stemmer ikke overens",
+ "confirmPasswordRequired": "Bekræft din adgangskode"
+ }
},
"Login": {
"title": "Log på",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Noget gik galt. Prøv igen senere.",
"passwordResetRequired": "Nulstilling af adgangskode påkrævet. Kontrollér din e-mail for instruktioner til at nulstille din adgangskode.",
"invalidToken": "Dit login-link er ugyldigt eller udløbet. Prøv at logge ind igen.",
+ "FieldErrors": {
+ "emailRequired": "E-mail er påkrævet",
+ "emailInvalid": "Indtast en gyldig e-mailadresse",
+ "passwordRequired": "Adgangskode er påkrævet",
+ "invalidInput": "Tjek din indtastning, og prøv igen."
+ },
"CreateAccount": {
"title": "Ny kunde?",
"accountBenefits": "Opret en konto hos os, og du vil kunne:",
@@ -70,14 +86,36 @@
"title": "Glemt adgangskode",
"subtitle": "Indtast den e-mail, der er knyttet til din konto, nedenfor. Vi sender dig instruktioner til nulstilling af din adgangskode.",
"confirmResetPassword": "Hvis e-mailadressen {email} er knyttet til en konto i vores butik, har vi sendt dig en e-mail til nulstilling af adgangskode. Tjek din indbakke og spam-mappe, hvis du ikke kan se den.",
- "somethingWentWrong": "Noget gik galt. Prøv igen senere."
+ "somethingWentWrong": "Noget gik galt. Prøv igen senere.",
+ "FieldErrors": {
+ "emailRequired": "E-mail er påkrævet",
+ "emailInvalid": "Indtast en gyldig e-mailadresse"
+ }
}
},
"Register": {
"title": "Registrer konto",
"heading": "Ny konto",
"cta": "Opret konto",
- "somethingWentWrong": "Noget gik galt. Prøv igen senere."
+ "somethingWentWrong": "Noget gik galt. Prøv igen senere.",
+ "FieldErrors": {
+ "firstNameRequired": "Fornavnet er påkrævet",
+ "lastNameRequired": "Efternavnet er påkrævet",
+ "emailRequired": "E-mail er påkrævet",
+ "emailInvalid": "Indtast en gyldig e-mailadresse",
+ "passwordRequired": "Adgangskode er påkrævet",
+ "passwordTooSmall": "Adgangskoden skal være på mindst {minLength, plural, =1 {1 character} other {# characters}}",
+ "passwordLowercaseRequired": "Adgangskoden skal indeholde mindst ét lille bogstav",
+ "passwordUppercaseRequired": "Adgangskoden skal indeholde mindst ét stort bogstav",
+ "passwordNumberRequired": "Adgangskoden skal indeholde mindst {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Adgangskoden skal indeholde mindst ét specialtegn",
+ "passwordsMustMatch": "Adgangskoderne stemmer ikke overens",
+ "addressLine1Required": "Adresselinje 1 er påkrævet",
+ "cityRequired": "Byen er påkrævet",
+ "countryRequired": "Landet er påkrævet",
+ "stateRequired": "Stat/region er påkrævet",
+ "postalCodeRequired": "Postnummeret er påkrævet"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Noget gik galt. Prøv igen senere.",
"EmptyState": {
"title": "Du har ingen adresser"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Fornavnet er påkrævet",
+ "lastNameRequired": "Efternavnet er påkrævet",
+ "addressLine1Required": "Adresselinje 1 er påkrævet",
+ "cityRequired": "Byen er påkrævet",
+ "countryRequired": "Landet er påkrævet",
+ "stateRequired": "Stat/region er påkrævet",
+ "postalCodeRequired": "Postnummeret er påkrævet"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Abonner på vores nyhedsbrev.",
"marketingPreferencesUpdated": "Markedsføringspræferencerne er blevet opdateret!",
"somethingWentWrong": "Noget gik galt. Prøv igen senere."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Fornavnet er påkrævet",
+ "firstNameTooSmall": "Fornavnet skal være på mindst 2 tegn",
+ "lastNameRequired": "Efternavnet er påkrævet",
+ "lastNameTooSmall": "Efternavnet skal være på mindst 2 tegn",
+ "emailRequired": "E-mail er påkrævet",
+ "emailInvalid": "Indtast en gyldig e-mailadresse",
+ "currentPasswordRequired": "Aktuel adgangskode er påkrævet",
+ "passwordRequired": "Adgangskode er påkrævet",
+ "passwordTooSmall": "Adgangskoden skal være på mindst {minLength, plural, =1 {1 character} other {# characters}}",
+ "passwordLowercaseRequired": "Adgangskoden skal indeholde mindst ét lille bogstav",
+ "passwordUppercaseRequired": "Adgangskoden skal indeholde mindst ét stort bogstav",
+ "passwordNumberRequired": "Adgangskoden skal indeholde mindst {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Adgangskoden skal indeholde mindst ét specialtegn",
+ "passwordsMustMatch": "Adgangskoderne stemmer ikke overens",
+ "confirmPasswordRequired": "Bekræft din adgangskode"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Vi bemærkede, at du havde gemt varer i en tidligere indkøbskurv, så vi har føjet dem til din nuværende indkøbskurv for dig.",
"cartRestored": "Du startede en indkøbskurv på en anden enhed, og vi har gendannet den her, så du kan fortsætte, hvor du slap.",
"cartUpdateInProgress": "Du har en igangværende opdatering af din indkøbskurv. Er du sikker på, at du vil forlade denne side? Dine ændringer kan gå tabt.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "Den oprindelige pris var {price}.",
+ "currentPrice": "Den aktuelle pris er {price}.",
+ "quantityReadyToShip": "{quantity, number} klar til forsendelse",
+ "quantityOnBackorder": "{antal, number} vil være i restordre",
+ "partiallyAvailable": "Kun {quantity, number} tilgængelig(e)",
"CheckoutSummary": {
"title": "Oversigt",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Opdater forsendelse",
"addShipping": "Tilføj forsendelse",
"cartNotFound": "Der opstod en fejl ved hentning af din indkøbskurv",
- "noShippingOptions": "Der er ingen tilgængelige forsendelsesmuligheder for din adresse"
+ "noShippingOptions": "Der er ingen tilgængelige forsendelsesmuligheder for din adresse",
+ "countryRequired": "Landet er påkrævet"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Yderligere oplysninger",
"currentStock": "{antal, number} på lager",
"backorderQuantity": "{antal, number} vil være i restordre",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Føj til kurv",
"outOfStock": "Udsolgt",
@@ -427,13 +497,24 @@
"button": "Skriv en anmeldelse",
"title": "Skriv en anmeldelse",
"submit": "Indsend",
+ "cancel": "Annuller",
"ratingLabel": "Bedømmelse",
"titleLabel": "Titel",
"reviewLabel": "Anmeldelse",
"nameLabel": "Navn",
"emailLabel": "E-mail",
"successMessage": "Din anmeldelse er blevet indsendt!",
- "somethingWentWrong": "Noget gik galt. Prøv igen senere."
+ "somethingWentWrong": "Noget gik galt. Prøv igen senere.",
+ "FieldErrors": {
+ "titleRequired": "Titel er påkrævet",
+ "authorRequired": "Navn er påkrævet",
+ "emailRequired": "E-mail er påkrævet",
+ "emailInvalid": "Indtast en gyldig e-mailadresse",
+ "textRequired": "Anmeldelse er påkrævet",
+ "ratingRequired": "Bedømmelse er påkrævet",
+ "ratingTooSmall": "Bedømmelsen skal være mindst 1",
+ "ratingTooLarge": "Bedømmelsen må højst være 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Hold dig opdateret med de seneste nyheder og tilbud fra vores butik.",
"subscribedToNewsletter": "Du er blevet tilmeldt vores nyhedsbrev!",
"Errors": {
- "invalidEmail": "Indtast en gyldig e-mailadresse.",
+ "emailRequired": "E-mail er påkrævet",
+ "invalidEmail": "Indtast en gyldig e-mailadresse",
"somethingWentWrong": "Noget gik galt. Prøv igen senere."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "Den oprindelige pris var {price}.",
+ "currentPrice": "Den aktuelle pris er {price}.",
+ "range": "Pris fra {minValue} til {maxValue}."
}
},
"GiftCertificates": {
@@ -574,7 +656,7 @@
"title": "Tjek saldo",
"description": "Du kan tjekke saldoen og få oplysninger om dit gavekort ved at indtaste koden i feltet nedenfor.",
"inputLabel": "Kode",
- "inputPlaceholder": "xxx-xxx-xxx-xxx",
+ "inputPlaceholder": "XXX-XXX-XXX-XXX",
"purchasedDateLabel": "Købt",
"senderLabel": "Fra",
"Errors": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Jeg accepterer, at dette gavekort udløber den {expiryDate}",
"ctaLabel": "Føj til kurv",
"Errors": {
- "amountRequired": "Vælg eller indtast et gavekortbeløb.",
- "amountInvalid": "Vælg et gyldigt gavekortbeløb.",
- "amountOutOfRange": "Indtast et beløb mellem {minAmount} og {maxAmount}.",
- "unexpectedSettingsError": "Der opstod en uventet fejl under hentning af indstillingerne for gavekort. Prøv igen senere."
+ "amountRequired": "Vælg eller indtast et gavekortbeløb",
+ "amountInvalid": "Vælg et gyldigt gavekortbeløb",
+ "amountOutOfRange": "Indtast et beløb mellem {minAmount} og {maxAmount}",
+ "unexpectedSettingsError": "Der opstod en uventet fejl under hentning af indstillingerne for gavekort. Prøv igen senere.",
+ "senderNameRequired": "Dit navn er påkrævet",
+ "senderEmailRequired": "Din e-mailadresse er påkrævet",
+ "recipientNameRequired": "Modtagerens navn er påkrævet",
+ "recipientEmailRequired": "Modtagerens e-mailadresse er påkrævet",
+ "emailInvalid": "Indtast en gyldig e-mailadresse",
+ "checkboxRequired": "Du skal sætte kryds i dette felt for at fortsætte"
}
}
}
},
"Form": {
- "optional": "Valgfrit"
+ "optional": "Valgfrit",
+ "Errors": {
+ "invalidInput": "Tjek din indtastning, og prøv igen",
+ "invalidFormat": "Den indtastede værdi stemmer ikke overens med det krævede format"
+ }
}
}
diff --git a/core/messages/de.json b/core/messages/de.json
index 317deae02..8a7db06ad 100644
--- a/core/messages/de.json
+++ b/core/messages/de.json
@@ -43,7 +43,17 @@
"newPassword": "Neues Passwort",
"confirmPassword": "Passwort bestätigen",
"passwordUpdated": "Passwort wurde erfolgreich aktualisiert!",
- "somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut."
+ "somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut.",
+ "FieldErrors": {
+ "passwordRequired": "Es muss ein Passwort angegeben werden",
+ "passwordTooSmall": "Das Passwort muss mindestens {minLength, plural, =1 {1 Zeichen} other {# Zeichen}} lang sein",
+ "passwordLowercaseRequired": "Das Passwort muss mindestens einen Kleinbuchstaben enthalten",
+ "passwordUppercaseRequired": "Das Passwort muss mindestens einen Großbuchstaben enthalten",
+ "passwordNumberRequired": "Das Passwort muss mindestens {minNumbers, plural, =1 {eine Zahl} other {# Zahlen}} enthalten",
+ "passwordSpecialCharacterRequired": "Das Passwort muss mindestens ein Sonderzeichen enthalten",
+ "passwordsMustMatch": "Die Passwörter stimmen nicht überein",
+ "confirmPasswordRequired": "Bitte bestätigen Sie Ihr Passwort"
+ }
},
"Login": {
"title": "Anmelden",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut.",
"passwordResetRequired": "Passwortzurücksetzung erforderlich. Bitte überprüfen Sie Ihre E-Mails für die Anleitung zum Zurücksetzen Ihres Passworts.",
"invalidToken": "Ihr Anmeldelink ist ungültig oder abgelaufen. Bitte versuchen Sie erneut, sich anzumelden.",
+ "FieldErrors": {
+ "emailRequired": "Die E-Mail-Adresse muss angegeben werden",
+ "emailInvalid": "Bitte geben Sie eine gültige E-Mail-Adresse an",
+ "passwordRequired": "Es muss ein Passwort angegeben werden",
+ "invalidInput": "Bitte überprüfen Sie Ihre Eingabe und versuchen Sie es erneut"
+ },
"CreateAccount": {
"title": "Neuer Kunde?",
"accountBenefits": "Wenn Sie ein Konto bei uns erstellen, haben Sie folgende Möglichkeiten:",
@@ -70,14 +86,36 @@
"title": "Passwort vergessen",
"subtitle": "Geben Sie unten die mit Ihrem Konto verknüpfte E-Mail-Adresse ein. Wir senden Ihnen Anweisungen zum Zurücksetzen Ihres Passworts.",
"confirmResetPassword": "Wenn die E-Mail-Adresse {email} mit einem Konto in unserem Geschäft verknüpft ist, haben wir Ihnen eine E-Mail zum Zurücksetzen des Passworts gesendet. Bitte überprüfen Sie Ihren Posteingang und Spam-Ordner, wenn Sie sie nicht sehen.",
- "somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut."
+ "somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut.",
+ "FieldErrors": {
+ "emailRequired": "Die E-Mail-Adresse muss angegeben werden",
+ "emailInvalid": "Bitte geben Sie eine gültige E-Mail-Adresse an"
+ }
}
},
"Register": {
"title": "Konto registrieren",
"heading": "Neues Konto",
"cta": "Konto erstellen",
- "somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut."
+ "somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut.",
+ "FieldErrors": {
+ "firstNameRequired": "Es muss ein Vorname angegeben werden",
+ "lastNameRequired": "Es muss ein Nachname angegeben werden",
+ "emailRequired": "Die E-Mail-Adresse muss angegeben werden",
+ "emailInvalid": "Bitte geben Sie eine gültige E-Mail-Adresse an",
+ "passwordRequired": "Es muss ein Passwort angegeben werden",
+ "passwordTooSmall": "Das Passwort muss mindestens {minLength, plural, =1 {1 Zeichen} other {# Zeichen}} lang sein",
+ "passwordLowercaseRequired": "Das Passwort muss mindestens einen Kleinbuchstaben enthalten",
+ "passwordUppercaseRequired": "Das Passwort muss mindestens einen Großbuchstaben enthalten",
+ "passwordNumberRequired": "Das Passwort muss mindestens {minNumbers, plural, =1 {eine Zahl} other {# Zahlen}} enthalten",
+ "passwordSpecialCharacterRequired": "Das Passwort muss mindestens ein Sonderzeichen enthalten",
+ "passwordsMustMatch": "Die Passwörter stimmen nicht überein",
+ "addressLine1Required": "Adresszeile 1 ist eine Pflichtangabe",
+ "cityRequired": "Ort ist eine Pflichtangabe",
+ "countryRequired": "Land ist eine Pflichtangabe",
+ "stateRequired": "Bundesstaat/Provinz ist eine Pflichtangabe",
+ "postalCodeRequired": "Postleitzahl ist erforderlich"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut.",
"EmptyState": {
"title": "Sie haben keine Adressen"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Es muss ein Vorname angegeben werden",
+ "lastNameRequired": "Es muss ein Nachname angegeben werden",
+ "addressLine1Required": "Adresszeile 1 ist eine Pflichtangabe",
+ "cityRequired": "Ort ist eine Pflichtangabe",
+ "countryRequired": "Land ist eine Pflichtangabe",
+ "stateRequired": "Bundesstaat/Provinz ist eine Pflichtangabe",
+ "postalCodeRequired": "Postleitzahl ist erforderlich"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Abonnieren Sie unseren Newsletter.",
"marketingPreferencesUpdated": "Marketingeinstellungen wurden erfolgreich aktualisiert!",
"somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Es muss ein Vorname angegeben werden",
+ "firstNameTooSmall": "„Vorname“ muss mindestens 2 Zeichen lang sei",
+ "lastNameRequired": "Es muss ein Nachname angegeben werden",
+ "lastNameTooSmall": "„Nachname“ muss mindestens 2 Zeichen lang sein",
+ "emailRequired": "Die E-Mail-Adresse muss angegeben werden",
+ "emailInvalid": "Bitte geben Sie eine gültige E-Mail-Adresse an",
+ "currentPasswordRequired": "Aktuelles Passwort ist erforderlich",
+ "passwordRequired": "Es muss ein Passwort angegeben werden",
+ "passwordTooSmall": "Das Passwort muss mindestens {minLength, plural, =1 {1 Zeichen} other {# Zeichen}} lang sein",
+ "passwordLowercaseRequired": "Das Passwort muss mindestens einen Kleinbuchstaben enthalten",
+ "passwordUppercaseRequired": "Das Passwort muss mindestens einen Großbuchstaben enthalten",
+ "passwordNumberRequired": "Das Passwort muss mindestens {minNumbers, plural, =1 {eine Zahl} other {# Zahlen}} enthalten",
+ "passwordSpecialCharacterRequired": "Das Passwort muss mindestens ein Sonderzeichen enthalten",
+ "passwordsMustMatch": "Die Passwörter stimmen nicht überein",
+ "confirmPasswordRequired": "Bitte bestätigen Sie Ihr Passwort"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Wir haben festgestellt, dass Sie Artikel in einem früheren Warenkorb gespeichert hatten, also haben wir diese Ihrem aktuellen Warenkorb hinzugefügt.",
"cartRestored": "Sie haben einen Warenkorb auf einem anderen Gerät angelegt, und wir haben ihn hier wiederhergestellt, damit Sie dort weitermachen können, wo Sie aufgehört haben.",
"cartUpdateInProgress": "Sie führen derzeit eine Aktualisierung Ihres Warenkorbs durch. Sind Sie sicher, dass Sie diese Seite verlassen möchten? Ihre Änderungen könnten verloren gehen.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "Der ursprüngliche Preis war {price}.",
+ "currentPrice": "Der aktuelle Preis beträgt {price}.",
+ "quantityReadyToShip": "{quantity, number} bereit zum Versand",
+ "quantityOnBackorder": "{quantity, number} wird nachbestellt",
+ "partiallyAvailable": "Nur {quantity, number} verfügbar",
"CheckoutSummary": {
"title": "Übersicht",
"subTotal": "Zwischensumme",
@@ -335,7 +402,8 @@
"updateShipping": "Versand aktualisieren",
"addShipping": "Versand hinzufügen",
"cartNotFound": "Beim Abrufen des Warenkorbs ist ein Fehler aufgetreten",
- "noShippingOptions": "Für Ihre Adresse sind keine Versandoptionen verfügbar"
+ "noShippingOptions": "Für Ihre Adresse sind keine Versandoptionen verfügbar",
+ "countryRequired": "Land ist eine Pflichtangabe"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Weitere Informationen",
"currentStock": "{quantity, number} auf Lager",
"backorderQuantity": "{quantity, number} wird nachbestellt",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Zum Warenkorb hinzufügen",
"outOfStock": "Kein Lagerbestand",
@@ -427,13 +497,24 @@
"button": "Eine Bewertung schreiben",
"title": "Eine Bewertung schreiben",
"submit": "Einreichen",
+ "cancel": "Abbrechen",
"ratingLabel": "Bewertung",
"titleLabel": "Titel",
"reviewLabel": "Bewertung",
"nameLabel": "Name",
"emailLabel": "E-Mail",
"successMessage": "Ihre Bewertung wurde erfolgreich übermittelt!",
- "somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut."
+ "somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut.",
+ "FieldErrors": {
+ "titleRequired": "Titel ist erforderlich",
+ "authorRequired": "Es muss ein Name angegeben werden",
+ "emailRequired": "Die E-Mail-Adresse muss angegeben werden",
+ "emailInvalid": "Bitte geben Sie eine gültige E-Mail-Adresse an",
+ "textRequired": "Überprüfung ist erforderlich",
+ "ratingRequired": "Bewertung ist erforderlich.",
+ "ratingTooSmall": "Die Bewertung muss mindestens 1 betragen",
+ "ratingTooLarge": "Die Bewertung darf höchstens 5 betragen"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Bleiben Sie auf dem Laufenden über die aktuellen Neuigkeiten und Angebote in unserem Shop.",
"subscribedToNewsletter": "Sie haben unseren Newsletter abonniert!",
"Errors": {
- "invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse an.",
+ "emailRequired": "Die E-Mail-Adresse muss angegeben werden",
+ "invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse an",
"somethingWentWrong": "Es ist etwas schiefgegangen Bitte versuchen Sie es später erneut."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "Der ursprüngliche Preis war {price}.",
+ "currentPrice": "Der aktuelle Preis beträgt {price}.",
+ "range": "Preis von {minValue} bis {maxValue}."
}
},
"GiftCertificates": {
@@ -574,7 +656,7 @@
"title": "Guthaben abfragen",
"description": "Sie können das Guthaben überprüfen und Informationen zu Ihrem Geschenkgutschein erhalten, indem Sie den Code in das Feld unten eingeben.",
"inputLabel": "Code",
- "inputPlaceholder": "xxx-xxx-xxx-xxx",
+ "inputPlaceholder": "XXX-XXX-XXX-XXX",
"purchasedDateLabel": "Gekauft",
"senderLabel": "Von",
"Errors": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Ich bestätige, dass dieser Geschenkgutschein am {expiryDate} abläuft.",
"ctaLabel": "Zum Warenkorb hinzufügen",
"Errors": {
- "amountRequired": "Bitte wählen Sie einen Geschenkgutscheinbetrag aus oder geben Sie ihn ein.",
- "amountInvalid": "Bitte wählen Sie einen gültigen Betrag für diesen Geschenkgutschein aus.",
- "amountOutOfRange": "Bitte geben Sie einen Betrag zwischen {minAmount} und {maxAmount} ein.",
- "unexpectedSettingsError": "Beim Abrufen der Geschenkgutscheineinstellungen ist ein unerwarteter Fehler aufgetreten. Bitte versuchen Sie es später erneut."
+ "amountRequired": "Bitte wählen Sie einen Geschenkgutscheinbetrag aus oder geben Sie ihn ein",
+ "amountInvalid": "Bitte wählen Sie einen gültigen Betrag für diesen Geschenkgutschein aus",
+ "amountOutOfRange": "Bitte geben Sie einen Betrag zwischen {minAmount} und {maxAmount} ein",
+ "unexpectedSettingsError": "Beim Abrufen der Geschenkgutscheineinstellungen ist ein unerwarteter Fehler aufgetreten. Bitte versuchen Sie es später erneut.",
+ "senderNameRequired": "Ihr Name ist erforderlich",
+ "senderEmailRequired": "Ihre E-Mail-Adresse ist erforderlich",
+ "recipientNameRequired": "Der Name des Empfängers ist erforderlich",
+ "recipientEmailRequired": "Die E-Mail-Adresse des Empfängers ist erforderlich",
+ "emailInvalid": "Bitte geben Sie eine gültige E-Mail-Adresse an",
+ "checkboxRequired": "Sie müssen dieses Feld ankreuzen, um fortzufahren"
}
}
}
},
"Form": {
- "optional": "optional"
+ "optional": "optional",
+ "Errors": {
+ "invalidInput": "Bitte überprüfen Sie Ihre Eingabe und versuchen Sie es erneut",
+ "invalidFormat": "Der eingegebene Wert entspricht nicht dem erforderlichen Format"
+ }
}
}
diff --git a/core/messages/es-419.json b/core/messages/es-419.json
index f98234073..93e494019 100644
--- a/core/messages/es-419.json
+++ b/core/messages/es-419.json
@@ -43,7 +43,17 @@
"newPassword": "Nueva contraseña",
"confirmPassword": "Confirmar contraseña",
"passwordUpdated": "¡La contraseña se actualizó correctamente!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
+ }
},
"Login": {
"title": "Inicio de sesión",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"passwordResetRequired": "Se requiere restablecimiento de contraseña. Por favor, revisa tu email para ver instrucciones para restablecer tu contraseña.",
"invalidToken": "Tu enlace de acceso es inválido o caducó. Por favor, intenta iniciar sesión de nuevo.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo."
+ },
"CreateAccount": {
"title": "¿Nuevo cliente?",
"accountBenefits": "Crea una cuenta con nosotros y podrás:",
@@ -70,14 +86,36 @@
"title": "Olvidé la contraseña",
"subtitle": "A continuación, ingresa el correo electrónico asociado a tu cuenta. Te enviaremos instrucciones para restablecer tu contraseña.",
"confirmResetPassword": "Si la dirección de correo electrónico {email} está vinculada a una cuenta en nuestra tienda, te hemos enviado un correo electrónico de restablecimiento de contraseña. Revisa tu bandeja de entrada y tu carpeta de correo no deseado si no lo ves.",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida"
+ }
}
},
"Register": {
"title": "Registrar cuenta",
"heading": "Cuenta nueva",
"cta": "Crear cuenta",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"EmptyState": {
"title": "No tienes ninguna dirección"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Suscríbete a nuestro boletín informativo.",
"marketingPreferencesUpdated": "¡Las preferencias de marketing se actualizaron con éxito!",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "firstNameTooSmall": "El nombre de pila debe tener al menos 2 caracteres",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "lastNameTooSmall": "El apellido debe tener al menos 2 caracteres",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "currentPasswordRequired": "La contraseña actual es obligatoria",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Notamos que tenías artículos guardados en un carrito anterior, así que los hemos agregado a tu carrito actual.",
"cartRestored": "Iniciaste un carrito en otro dispositivo y lo hemos restaurado aquí para que puedas continuar desde donde lo dejaste.",
"cartUpdateInProgress": "Tiene una actualización de carrito en proceso. ¿Estás seguro de que quieres salir de esta página? Es posible que se pierdan sus cambios.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "quantityReadyToShip": "{cantidad, número} listo para enviar",
+ "quantityOnBackorder": "{cantidad, número} estará en pedido pendiente",
+ "partiallyAvailable": "Solo {cantidad, número} disponible",
"CheckoutSummary": {
"title": "Resumen",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Actualizar envío",
"addShipping": "Agregar envío",
"cartNotFound": "Se produjo un error al recuperar su carrito",
- "noShippingOptions": "No hay opciones de envío disponibles para tu dirección"
+ "noShippingOptions": "No hay opciones de envío disponibles para tu dirección",
+ "countryRequired": "País es un campo obligatorio"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
@@ -427,13 +497,24 @@
"button": "Escribe una opinión",
"title": "Escribe una opinión",
"submit": "Enviar",
+ "cancel": "Cancelar",
"ratingLabel": "Calificación",
"titleLabel": "Título",
"reviewLabel": "Revisar",
"nameLabel": "Nombre",
"emailLabel": "Correo electrónico",
"successMessage": "¡Tu reseña fue enviada con éxito!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "titleRequired": "Se requiere título",
+ "authorRequired": "El campo Nombre es obligatorio",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "textRequired": "Es necesario revisar",
+ "ratingRequired": "Se requiere una calificación",
+ "ratingTooSmall": "La puntuación debe ser al menos 1",
+ "ratingTooLarge": "El puntaje debe ser como máximo 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Mantente al día con las últimas noticias y ofertas de nuestra tienda.",
"subscribedToNewsletter": "¡Te suscribiste a nuestro boletín!",
"Errors": {
- "invalidEmail": "Ingrese una dirección de correo electrónico válida.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "invalidEmail": "Por favor, introduzca una dirección de email válida",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "range": "Precio de {minValue} a {maxValue}."
}
},
"GiftCertificates": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Reconozco que este Certificado de Regalo caducará el {expiryDate}",
"ctaLabel": "Agregar al carrito",
"Errors": {
- "amountRequired": "Seleccione o ingrese el monto de un certificado de regalo.",
- "amountInvalid": "Seleccione un monto de certificado de regalo válido.",
- "amountOutOfRange": "Ingrese una cantidad entre {minAmount} y {maxAmount}.",
- "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde."
+ "amountRequired": "Por favor, selecciona o introduce el importe de un vale regalo",
+ "amountInvalid": "Por favor, seleccione un importe válido de un certificado regalo",
+ "amountOutOfRange": "Por favor, introduzca una cantidad entre {minAmount} y {maxAmount}",
+ "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde.",
+ "senderNameRequired": "Tu nombre es obligatorio",
+ "senderEmailRequired": "Tu correo electrónico es obligatorio",
+ "recipientNameRequired": "Se requiere el nombre del destinatario",
+ "recipientEmailRequired": "Se requiere el email del destinatario",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "checkboxRequired": "Debes marcar esta casilla para continuar"
}
}
}
},
"Form": {
- "optional": "Opcional"
+ "optional": "Opcional",
+ "Errors": {
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo",
+ "invalidFormat": "El valor introducido no coincide con el formato requerido"
+ }
}
}
diff --git a/core/messages/es-AR.json b/core/messages/es-AR.json
index f98234073..93e494019 100644
--- a/core/messages/es-AR.json
+++ b/core/messages/es-AR.json
@@ -43,7 +43,17 @@
"newPassword": "Nueva contraseña",
"confirmPassword": "Confirmar contraseña",
"passwordUpdated": "¡La contraseña se actualizó correctamente!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
+ }
},
"Login": {
"title": "Inicio de sesión",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"passwordResetRequired": "Se requiere restablecimiento de contraseña. Por favor, revisa tu email para ver instrucciones para restablecer tu contraseña.",
"invalidToken": "Tu enlace de acceso es inválido o caducó. Por favor, intenta iniciar sesión de nuevo.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo."
+ },
"CreateAccount": {
"title": "¿Nuevo cliente?",
"accountBenefits": "Crea una cuenta con nosotros y podrás:",
@@ -70,14 +86,36 @@
"title": "Olvidé la contraseña",
"subtitle": "A continuación, ingresa el correo electrónico asociado a tu cuenta. Te enviaremos instrucciones para restablecer tu contraseña.",
"confirmResetPassword": "Si la dirección de correo electrónico {email} está vinculada a una cuenta en nuestra tienda, te hemos enviado un correo electrónico de restablecimiento de contraseña. Revisa tu bandeja de entrada y tu carpeta de correo no deseado si no lo ves.",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida"
+ }
}
},
"Register": {
"title": "Registrar cuenta",
"heading": "Cuenta nueva",
"cta": "Crear cuenta",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"EmptyState": {
"title": "No tienes ninguna dirección"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Suscríbete a nuestro boletín informativo.",
"marketingPreferencesUpdated": "¡Las preferencias de marketing se actualizaron con éxito!",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "firstNameTooSmall": "El nombre de pila debe tener al menos 2 caracteres",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "lastNameTooSmall": "El apellido debe tener al menos 2 caracteres",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "currentPasswordRequired": "La contraseña actual es obligatoria",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Notamos que tenías artículos guardados en un carrito anterior, así que los hemos agregado a tu carrito actual.",
"cartRestored": "Iniciaste un carrito en otro dispositivo y lo hemos restaurado aquí para que puedas continuar desde donde lo dejaste.",
"cartUpdateInProgress": "Tiene una actualización de carrito en proceso. ¿Estás seguro de que quieres salir de esta página? Es posible que se pierdan sus cambios.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "quantityReadyToShip": "{cantidad, número} listo para enviar",
+ "quantityOnBackorder": "{cantidad, número} estará en pedido pendiente",
+ "partiallyAvailable": "Solo {cantidad, número} disponible",
"CheckoutSummary": {
"title": "Resumen",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Actualizar envío",
"addShipping": "Agregar envío",
"cartNotFound": "Se produjo un error al recuperar su carrito",
- "noShippingOptions": "No hay opciones de envío disponibles para tu dirección"
+ "noShippingOptions": "No hay opciones de envío disponibles para tu dirección",
+ "countryRequired": "País es un campo obligatorio"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
@@ -427,13 +497,24 @@
"button": "Escribe una opinión",
"title": "Escribe una opinión",
"submit": "Enviar",
+ "cancel": "Cancelar",
"ratingLabel": "Calificación",
"titleLabel": "Título",
"reviewLabel": "Revisar",
"nameLabel": "Nombre",
"emailLabel": "Correo electrónico",
"successMessage": "¡Tu reseña fue enviada con éxito!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "titleRequired": "Se requiere título",
+ "authorRequired": "El campo Nombre es obligatorio",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "textRequired": "Es necesario revisar",
+ "ratingRequired": "Se requiere una calificación",
+ "ratingTooSmall": "La puntuación debe ser al menos 1",
+ "ratingTooLarge": "El puntaje debe ser como máximo 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Mantente al día con las últimas noticias y ofertas de nuestra tienda.",
"subscribedToNewsletter": "¡Te suscribiste a nuestro boletín!",
"Errors": {
- "invalidEmail": "Ingrese una dirección de correo electrónico válida.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "invalidEmail": "Por favor, introduzca una dirección de email válida",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "range": "Precio de {minValue} a {maxValue}."
}
},
"GiftCertificates": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Reconozco que este Certificado de Regalo caducará el {expiryDate}",
"ctaLabel": "Agregar al carrito",
"Errors": {
- "amountRequired": "Seleccione o ingrese el monto de un certificado de regalo.",
- "amountInvalid": "Seleccione un monto de certificado de regalo válido.",
- "amountOutOfRange": "Ingrese una cantidad entre {minAmount} y {maxAmount}.",
- "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde."
+ "amountRequired": "Por favor, selecciona o introduce el importe de un vale regalo",
+ "amountInvalid": "Por favor, seleccione un importe válido de un certificado regalo",
+ "amountOutOfRange": "Por favor, introduzca una cantidad entre {minAmount} y {maxAmount}",
+ "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde.",
+ "senderNameRequired": "Tu nombre es obligatorio",
+ "senderEmailRequired": "Tu correo electrónico es obligatorio",
+ "recipientNameRequired": "Se requiere el nombre del destinatario",
+ "recipientEmailRequired": "Se requiere el email del destinatario",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "checkboxRequired": "Debes marcar esta casilla para continuar"
}
}
}
},
"Form": {
- "optional": "Opcional"
+ "optional": "Opcional",
+ "Errors": {
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo",
+ "invalidFormat": "El valor introducido no coincide con el formato requerido"
+ }
}
}
diff --git a/core/messages/es-CL.json b/core/messages/es-CL.json
index f98234073..93e494019 100644
--- a/core/messages/es-CL.json
+++ b/core/messages/es-CL.json
@@ -43,7 +43,17 @@
"newPassword": "Nueva contraseña",
"confirmPassword": "Confirmar contraseña",
"passwordUpdated": "¡La contraseña se actualizó correctamente!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
+ }
},
"Login": {
"title": "Inicio de sesión",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"passwordResetRequired": "Se requiere restablecimiento de contraseña. Por favor, revisa tu email para ver instrucciones para restablecer tu contraseña.",
"invalidToken": "Tu enlace de acceso es inválido o caducó. Por favor, intenta iniciar sesión de nuevo.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo."
+ },
"CreateAccount": {
"title": "¿Nuevo cliente?",
"accountBenefits": "Crea una cuenta con nosotros y podrás:",
@@ -70,14 +86,36 @@
"title": "Olvidé la contraseña",
"subtitle": "A continuación, ingresa el correo electrónico asociado a tu cuenta. Te enviaremos instrucciones para restablecer tu contraseña.",
"confirmResetPassword": "Si la dirección de correo electrónico {email} está vinculada a una cuenta en nuestra tienda, te hemos enviado un correo electrónico de restablecimiento de contraseña. Revisa tu bandeja de entrada y tu carpeta de correo no deseado si no lo ves.",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida"
+ }
}
},
"Register": {
"title": "Registrar cuenta",
"heading": "Cuenta nueva",
"cta": "Crear cuenta",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"EmptyState": {
"title": "No tienes ninguna dirección"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Suscríbete a nuestro boletín informativo.",
"marketingPreferencesUpdated": "¡Las preferencias de marketing se actualizaron con éxito!",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "firstNameTooSmall": "El nombre de pila debe tener al menos 2 caracteres",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "lastNameTooSmall": "El apellido debe tener al menos 2 caracteres",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "currentPasswordRequired": "La contraseña actual es obligatoria",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Notamos que tenías artículos guardados en un carrito anterior, así que los hemos agregado a tu carrito actual.",
"cartRestored": "Iniciaste un carrito en otro dispositivo y lo hemos restaurado aquí para que puedas continuar desde donde lo dejaste.",
"cartUpdateInProgress": "Tiene una actualización de carrito en proceso. ¿Estás seguro de que quieres salir de esta página? Es posible que se pierdan sus cambios.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "quantityReadyToShip": "{cantidad, número} listo para enviar",
+ "quantityOnBackorder": "{cantidad, número} estará en pedido pendiente",
+ "partiallyAvailable": "Solo {cantidad, número} disponible",
"CheckoutSummary": {
"title": "Resumen",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Actualizar envío",
"addShipping": "Agregar envío",
"cartNotFound": "Se produjo un error al recuperar su carrito",
- "noShippingOptions": "No hay opciones de envío disponibles para tu dirección"
+ "noShippingOptions": "No hay opciones de envío disponibles para tu dirección",
+ "countryRequired": "País es un campo obligatorio"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
@@ -427,13 +497,24 @@
"button": "Escribe una opinión",
"title": "Escribe una opinión",
"submit": "Enviar",
+ "cancel": "Cancelar",
"ratingLabel": "Calificación",
"titleLabel": "Título",
"reviewLabel": "Revisar",
"nameLabel": "Nombre",
"emailLabel": "Correo electrónico",
"successMessage": "¡Tu reseña fue enviada con éxito!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "titleRequired": "Se requiere título",
+ "authorRequired": "El campo Nombre es obligatorio",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "textRequired": "Es necesario revisar",
+ "ratingRequired": "Se requiere una calificación",
+ "ratingTooSmall": "La puntuación debe ser al menos 1",
+ "ratingTooLarge": "El puntaje debe ser como máximo 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Mantente al día con las últimas noticias y ofertas de nuestra tienda.",
"subscribedToNewsletter": "¡Te suscribiste a nuestro boletín!",
"Errors": {
- "invalidEmail": "Ingrese una dirección de correo electrónico válida.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "invalidEmail": "Por favor, introduzca una dirección de email válida",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "range": "Precio de {minValue} a {maxValue}."
}
},
"GiftCertificates": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Reconozco que este Certificado de Regalo caducará el {expiryDate}",
"ctaLabel": "Agregar al carrito",
"Errors": {
- "amountRequired": "Seleccione o ingrese el monto de un certificado de regalo.",
- "amountInvalid": "Seleccione un monto de certificado de regalo válido.",
- "amountOutOfRange": "Ingrese una cantidad entre {minAmount} y {maxAmount}.",
- "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde."
+ "amountRequired": "Por favor, selecciona o introduce el importe de un vale regalo",
+ "amountInvalid": "Por favor, seleccione un importe válido de un certificado regalo",
+ "amountOutOfRange": "Por favor, introduzca una cantidad entre {minAmount} y {maxAmount}",
+ "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde.",
+ "senderNameRequired": "Tu nombre es obligatorio",
+ "senderEmailRequired": "Tu correo electrónico es obligatorio",
+ "recipientNameRequired": "Se requiere el nombre del destinatario",
+ "recipientEmailRequired": "Se requiere el email del destinatario",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "checkboxRequired": "Debes marcar esta casilla para continuar"
}
}
}
},
"Form": {
- "optional": "Opcional"
+ "optional": "Opcional",
+ "Errors": {
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo",
+ "invalidFormat": "El valor introducido no coincide con el formato requerido"
+ }
}
}
diff --git a/core/messages/es-CO.json b/core/messages/es-CO.json
index f98234073..93e494019 100644
--- a/core/messages/es-CO.json
+++ b/core/messages/es-CO.json
@@ -43,7 +43,17 @@
"newPassword": "Nueva contraseña",
"confirmPassword": "Confirmar contraseña",
"passwordUpdated": "¡La contraseña se actualizó correctamente!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
+ }
},
"Login": {
"title": "Inicio de sesión",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"passwordResetRequired": "Se requiere restablecimiento de contraseña. Por favor, revisa tu email para ver instrucciones para restablecer tu contraseña.",
"invalidToken": "Tu enlace de acceso es inválido o caducó. Por favor, intenta iniciar sesión de nuevo.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo."
+ },
"CreateAccount": {
"title": "¿Nuevo cliente?",
"accountBenefits": "Crea una cuenta con nosotros y podrás:",
@@ -70,14 +86,36 @@
"title": "Olvidé la contraseña",
"subtitle": "A continuación, ingresa el correo electrónico asociado a tu cuenta. Te enviaremos instrucciones para restablecer tu contraseña.",
"confirmResetPassword": "Si la dirección de correo electrónico {email} está vinculada a una cuenta en nuestra tienda, te hemos enviado un correo electrónico de restablecimiento de contraseña. Revisa tu bandeja de entrada y tu carpeta de correo no deseado si no lo ves.",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida"
+ }
}
},
"Register": {
"title": "Registrar cuenta",
"heading": "Cuenta nueva",
"cta": "Crear cuenta",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"EmptyState": {
"title": "No tienes ninguna dirección"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Suscríbete a nuestro boletín informativo.",
"marketingPreferencesUpdated": "¡Las preferencias de marketing se actualizaron con éxito!",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "firstNameTooSmall": "El nombre de pila debe tener al menos 2 caracteres",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "lastNameTooSmall": "El apellido debe tener al menos 2 caracteres",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "currentPasswordRequired": "La contraseña actual es obligatoria",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Notamos que tenías artículos guardados en un carrito anterior, así que los hemos agregado a tu carrito actual.",
"cartRestored": "Iniciaste un carrito en otro dispositivo y lo hemos restaurado aquí para que puedas continuar desde donde lo dejaste.",
"cartUpdateInProgress": "Tiene una actualización de carrito en proceso. ¿Estás seguro de que quieres salir de esta página? Es posible que se pierdan sus cambios.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "quantityReadyToShip": "{cantidad, número} listo para enviar",
+ "quantityOnBackorder": "{cantidad, número} estará en pedido pendiente",
+ "partiallyAvailable": "Solo {cantidad, número} disponible",
"CheckoutSummary": {
"title": "Resumen",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Actualizar envío",
"addShipping": "Agregar envío",
"cartNotFound": "Se produjo un error al recuperar su carrito",
- "noShippingOptions": "No hay opciones de envío disponibles para tu dirección"
+ "noShippingOptions": "No hay opciones de envío disponibles para tu dirección",
+ "countryRequired": "País es un campo obligatorio"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
@@ -427,13 +497,24 @@
"button": "Escribe una opinión",
"title": "Escribe una opinión",
"submit": "Enviar",
+ "cancel": "Cancelar",
"ratingLabel": "Calificación",
"titleLabel": "Título",
"reviewLabel": "Revisar",
"nameLabel": "Nombre",
"emailLabel": "Correo electrónico",
"successMessage": "¡Tu reseña fue enviada con éxito!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "titleRequired": "Se requiere título",
+ "authorRequired": "El campo Nombre es obligatorio",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "textRequired": "Es necesario revisar",
+ "ratingRequired": "Se requiere una calificación",
+ "ratingTooSmall": "La puntuación debe ser al menos 1",
+ "ratingTooLarge": "El puntaje debe ser como máximo 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Mantente al día con las últimas noticias y ofertas de nuestra tienda.",
"subscribedToNewsletter": "¡Te suscribiste a nuestro boletín!",
"Errors": {
- "invalidEmail": "Ingrese una dirección de correo electrónico válida.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "invalidEmail": "Por favor, introduzca una dirección de email válida",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "range": "Precio de {minValue} a {maxValue}."
}
},
"GiftCertificates": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Reconozco que este Certificado de Regalo caducará el {expiryDate}",
"ctaLabel": "Agregar al carrito",
"Errors": {
- "amountRequired": "Seleccione o ingrese el monto de un certificado de regalo.",
- "amountInvalid": "Seleccione un monto de certificado de regalo válido.",
- "amountOutOfRange": "Ingrese una cantidad entre {minAmount} y {maxAmount}.",
- "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde."
+ "amountRequired": "Por favor, selecciona o introduce el importe de un vale regalo",
+ "amountInvalid": "Por favor, seleccione un importe válido de un certificado regalo",
+ "amountOutOfRange": "Por favor, introduzca una cantidad entre {minAmount} y {maxAmount}",
+ "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde.",
+ "senderNameRequired": "Tu nombre es obligatorio",
+ "senderEmailRequired": "Tu correo electrónico es obligatorio",
+ "recipientNameRequired": "Se requiere el nombre del destinatario",
+ "recipientEmailRequired": "Se requiere el email del destinatario",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "checkboxRequired": "Debes marcar esta casilla para continuar"
}
}
}
},
"Form": {
- "optional": "Opcional"
+ "optional": "Opcional",
+ "Errors": {
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo",
+ "invalidFormat": "El valor introducido no coincide con el formato requerido"
+ }
}
}
diff --git a/core/messages/es-LA.json b/core/messages/es-LA.json
index f98234073..93e494019 100644
--- a/core/messages/es-LA.json
+++ b/core/messages/es-LA.json
@@ -43,7 +43,17 @@
"newPassword": "Nueva contraseña",
"confirmPassword": "Confirmar contraseña",
"passwordUpdated": "¡La contraseña se actualizó correctamente!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
+ }
},
"Login": {
"title": "Inicio de sesión",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"passwordResetRequired": "Se requiere restablecimiento de contraseña. Por favor, revisa tu email para ver instrucciones para restablecer tu contraseña.",
"invalidToken": "Tu enlace de acceso es inválido o caducó. Por favor, intenta iniciar sesión de nuevo.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo."
+ },
"CreateAccount": {
"title": "¿Nuevo cliente?",
"accountBenefits": "Crea una cuenta con nosotros y podrás:",
@@ -70,14 +86,36 @@
"title": "Olvidé la contraseña",
"subtitle": "A continuación, ingresa el correo electrónico asociado a tu cuenta. Te enviaremos instrucciones para restablecer tu contraseña.",
"confirmResetPassword": "Si la dirección de correo electrónico {email} está vinculada a una cuenta en nuestra tienda, te hemos enviado un correo electrónico de restablecimiento de contraseña. Revisa tu bandeja de entrada y tu carpeta de correo no deseado si no lo ves.",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida"
+ }
}
},
"Register": {
"title": "Registrar cuenta",
"heading": "Cuenta nueva",
"cta": "Crear cuenta",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"EmptyState": {
"title": "No tienes ninguna dirección"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Suscríbete a nuestro boletín informativo.",
"marketingPreferencesUpdated": "¡Las preferencias de marketing se actualizaron con éxito!",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "firstNameTooSmall": "El nombre de pila debe tener al menos 2 caracteres",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "lastNameTooSmall": "El apellido debe tener al menos 2 caracteres",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "currentPasswordRequired": "La contraseña actual es obligatoria",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Notamos que tenías artículos guardados en un carrito anterior, así que los hemos agregado a tu carrito actual.",
"cartRestored": "Iniciaste un carrito en otro dispositivo y lo hemos restaurado aquí para que puedas continuar desde donde lo dejaste.",
"cartUpdateInProgress": "Tiene una actualización de carrito en proceso. ¿Estás seguro de que quieres salir de esta página? Es posible que se pierdan sus cambios.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "quantityReadyToShip": "{cantidad, número} listo para enviar",
+ "quantityOnBackorder": "{cantidad, número} estará en pedido pendiente",
+ "partiallyAvailable": "Solo {cantidad, número} disponible",
"CheckoutSummary": {
"title": "Resumen",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Actualizar envío",
"addShipping": "Agregar envío",
"cartNotFound": "Se produjo un error al recuperar su carrito",
- "noShippingOptions": "No hay opciones de envío disponibles para tu dirección"
+ "noShippingOptions": "No hay opciones de envío disponibles para tu dirección",
+ "countryRequired": "País es un campo obligatorio"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
@@ -427,13 +497,24 @@
"button": "Escribe una opinión",
"title": "Escribe una opinión",
"submit": "Enviar",
+ "cancel": "Cancelar",
"ratingLabel": "Calificación",
"titleLabel": "Título",
"reviewLabel": "Revisar",
"nameLabel": "Nombre",
"emailLabel": "Correo electrónico",
"successMessage": "¡Tu reseña fue enviada con éxito!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "titleRequired": "Se requiere título",
+ "authorRequired": "El campo Nombre es obligatorio",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "textRequired": "Es necesario revisar",
+ "ratingRequired": "Se requiere una calificación",
+ "ratingTooSmall": "La puntuación debe ser al menos 1",
+ "ratingTooLarge": "El puntaje debe ser como máximo 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Mantente al día con las últimas noticias y ofertas de nuestra tienda.",
"subscribedToNewsletter": "¡Te suscribiste a nuestro boletín!",
"Errors": {
- "invalidEmail": "Ingrese una dirección de correo electrónico válida.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "invalidEmail": "Por favor, introduzca una dirección de email válida",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "range": "Precio de {minValue} a {maxValue}."
}
},
"GiftCertificates": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Reconozco que este Certificado de Regalo caducará el {expiryDate}",
"ctaLabel": "Agregar al carrito",
"Errors": {
- "amountRequired": "Seleccione o ingrese el monto de un certificado de regalo.",
- "amountInvalid": "Seleccione un monto de certificado de regalo válido.",
- "amountOutOfRange": "Ingrese una cantidad entre {minAmount} y {maxAmount}.",
- "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde."
+ "amountRequired": "Por favor, selecciona o introduce el importe de un vale regalo",
+ "amountInvalid": "Por favor, seleccione un importe válido de un certificado regalo",
+ "amountOutOfRange": "Por favor, introduzca una cantidad entre {minAmount} y {maxAmount}",
+ "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde.",
+ "senderNameRequired": "Tu nombre es obligatorio",
+ "senderEmailRequired": "Tu correo electrónico es obligatorio",
+ "recipientNameRequired": "Se requiere el nombre del destinatario",
+ "recipientEmailRequired": "Se requiere el email del destinatario",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "checkboxRequired": "Debes marcar esta casilla para continuar"
}
}
}
},
"Form": {
- "optional": "Opcional"
+ "optional": "Opcional",
+ "Errors": {
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo",
+ "invalidFormat": "El valor introducido no coincide con el formato requerido"
+ }
}
}
diff --git a/core/messages/es-MX.json b/core/messages/es-MX.json
index f98234073..93e494019 100644
--- a/core/messages/es-MX.json
+++ b/core/messages/es-MX.json
@@ -43,7 +43,17 @@
"newPassword": "Nueva contraseña",
"confirmPassword": "Confirmar contraseña",
"passwordUpdated": "¡La contraseña se actualizó correctamente!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
+ }
},
"Login": {
"title": "Inicio de sesión",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"passwordResetRequired": "Se requiere restablecimiento de contraseña. Por favor, revisa tu email para ver instrucciones para restablecer tu contraseña.",
"invalidToken": "Tu enlace de acceso es inválido o caducó. Por favor, intenta iniciar sesión de nuevo.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo."
+ },
"CreateAccount": {
"title": "¿Nuevo cliente?",
"accountBenefits": "Crea una cuenta con nosotros y podrás:",
@@ -70,14 +86,36 @@
"title": "Olvidé la contraseña",
"subtitle": "A continuación, ingresa el correo electrónico asociado a tu cuenta. Te enviaremos instrucciones para restablecer tu contraseña.",
"confirmResetPassword": "Si la dirección de correo electrónico {email} está vinculada a una cuenta en nuestra tienda, te hemos enviado un correo electrónico de restablecimiento de contraseña. Revisa tu bandeja de entrada y tu carpeta de correo no deseado si no lo ves.",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida"
+ }
}
},
"Register": {
"title": "Registrar cuenta",
"heading": "Cuenta nueva",
"cta": "Crear cuenta",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"EmptyState": {
"title": "No tienes ninguna dirección"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Suscríbete a nuestro boletín informativo.",
"marketingPreferencesUpdated": "¡Las preferencias de marketing se actualizaron con éxito!",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "firstNameTooSmall": "El nombre de pila debe tener al menos 2 caracteres",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "lastNameTooSmall": "El apellido debe tener al menos 2 caracteres",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "currentPasswordRequired": "La contraseña actual es obligatoria",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Notamos que tenías artículos guardados en un carrito anterior, así que los hemos agregado a tu carrito actual.",
"cartRestored": "Iniciaste un carrito en otro dispositivo y lo hemos restaurado aquí para que puedas continuar desde donde lo dejaste.",
"cartUpdateInProgress": "Tiene una actualización de carrito en proceso. ¿Estás seguro de que quieres salir de esta página? Es posible que se pierdan sus cambios.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "quantityReadyToShip": "{cantidad, número} listo para enviar",
+ "quantityOnBackorder": "{cantidad, número} estará en pedido pendiente",
+ "partiallyAvailable": "Solo {cantidad, número} disponible",
"CheckoutSummary": {
"title": "Resumen",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Actualizar envío",
"addShipping": "Agregar envío",
"cartNotFound": "Se produjo un error al recuperar su carrito",
- "noShippingOptions": "No hay opciones de envío disponibles para tu dirección"
+ "noShippingOptions": "No hay opciones de envío disponibles para tu dirección",
+ "countryRequired": "País es un campo obligatorio"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
@@ -427,13 +497,24 @@
"button": "Escribe una opinión",
"title": "Escribe una opinión",
"submit": "Enviar",
+ "cancel": "Cancelar",
"ratingLabel": "Calificación",
"titleLabel": "Título",
"reviewLabel": "Revisar",
"nameLabel": "Nombre",
"emailLabel": "Correo electrónico",
"successMessage": "¡Tu reseña fue enviada con éxito!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "titleRequired": "Se requiere título",
+ "authorRequired": "El campo Nombre es obligatorio",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "textRequired": "Es necesario revisar",
+ "ratingRequired": "Se requiere una calificación",
+ "ratingTooSmall": "La puntuación debe ser al menos 1",
+ "ratingTooLarge": "El puntaje debe ser como máximo 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Mantente al día con las últimas noticias y ofertas de nuestra tienda.",
"subscribedToNewsletter": "¡Te suscribiste a nuestro boletín!",
"Errors": {
- "invalidEmail": "Ingrese una dirección de correo electrónico válida.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "invalidEmail": "Por favor, introduzca una dirección de email válida",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "range": "Precio de {minValue} a {maxValue}."
}
},
"GiftCertificates": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Reconozco que este Certificado de Regalo caducará el {expiryDate}",
"ctaLabel": "Agregar al carrito",
"Errors": {
- "amountRequired": "Seleccione o ingrese el monto de un certificado de regalo.",
- "amountInvalid": "Seleccione un monto de certificado de regalo válido.",
- "amountOutOfRange": "Ingrese una cantidad entre {minAmount} y {maxAmount}.",
- "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde."
+ "amountRequired": "Por favor, selecciona o introduce el importe de un vale regalo",
+ "amountInvalid": "Por favor, seleccione un importe válido de un certificado regalo",
+ "amountOutOfRange": "Por favor, introduzca una cantidad entre {minAmount} y {maxAmount}",
+ "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde.",
+ "senderNameRequired": "Tu nombre es obligatorio",
+ "senderEmailRequired": "Tu correo electrónico es obligatorio",
+ "recipientNameRequired": "Se requiere el nombre del destinatario",
+ "recipientEmailRequired": "Se requiere el email del destinatario",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "checkboxRequired": "Debes marcar esta casilla para continuar"
}
}
}
},
"Form": {
- "optional": "Opcional"
+ "optional": "Opcional",
+ "Errors": {
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo",
+ "invalidFormat": "El valor introducido no coincide con el formato requerido"
+ }
}
}
diff --git a/core/messages/es-PE.json b/core/messages/es-PE.json
index f98234073..93e494019 100644
--- a/core/messages/es-PE.json
+++ b/core/messages/es-PE.json
@@ -43,7 +43,17 @@
"newPassword": "Nueva contraseña",
"confirmPassword": "Confirmar contraseña",
"passwordUpdated": "¡La contraseña se actualizó correctamente!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
+ }
},
"Login": {
"title": "Inicio de sesión",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"passwordResetRequired": "Se requiere restablecimiento de contraseña. Por favor, revisa tu email para ver instrucciones para restablecer tu contraseña.",
"invalidToken": "Tu enlace de acceso es inválido o caducó. Por favor, intenta iniciar sesión de nuevo.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo."
+ },
"CreateAccount": {
"title": "¿Nuevo cliente?",
"accountBenefits": "Crea una cuenta con nosotros y podrás:",
@@ -70,14 +86,36 @@
"title": "Olvidé la contraseña",
"subtitle": "A continuación, ingresa el correo electrónico asociado a tu cuenta. Te enviaremos instrucciones para restablecer tu contraseña.",
"confirmResetPassword": "Si la dirección de correo electrónico {email} está vinculada a una cuenta en nuestra tienda, te hemos enviado un correo electrónico de restablecimiento de contraseña. Revisa tu bandeja de entrada y tu carpeta de correo no deseado si no lo ves.",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida"
+ }
}
},
"Register": {
"title": "Registrar cuenta",
"heading": "Cuenta nueva",
"cta": "Crear cuenta",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"EmptyState": {
"title": "No tienes ninguna dirección"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "addressLine1Required": "La línea 1 es obligatoria",
+ "cityRequired": "La ciudad es obligatoria",
+ "countryRequired": "País es un campo obligatorio",
+ "stateRequired": "Estado/Provincia es un campo obligatorio.",
+ "postalCodeRequired": "El campo Código postal es obligatorio."
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Suscríbete a nuestro boletín informativo.",
"marketingPreferencesUpdated": "¡Las preferencias de marketing se actualizaron con éxito!",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "firstNameTooSmall": "El nombre de pila debe tener al menos 2 caracteres",
+ "lastNameRequired": "El campo Apellido es obligatorio.",
+ "lastNameTooSmall": "El apellido debe tener al menos 2 caracteres",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "currentPasswordRequired": "La contraseña actual es obligatoria",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe ser al menos {minLength, plural, =1 {1 carácter} other {# caracteres}} longitud",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Por favor, confirme tu contraseña"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Notamos que tenías artículos guardados en un carrito anterior, así que los hemos agregado a tu carrito actual.",
"cartRestored": "Iniciaste un carrito en otro dispositivo y lo hemos restaurado aquí para que puedas continuar desde donde lo dejaste.",
"cartUpdateInProgress": "Tiene una actualización de carrito en proceso. ¿Estás seguro de que quieres salir de esta página? Es posible que se pierdan sus cambios.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "quantityReadyToShip": "{cantidad, número} listo para enviar",
+ "quantityOnBackorder": "{cantidad, número} estará en pedido pendiente",
+ "partiallyAvailable": "Solo {cantidad, número} disponible",
"CheckoutSummary": {
"title": "Resumen",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Actualizar envío",
"addShipping": "Agregar envío",
"cartNotFound": "Se produjo un error al recuperar su carrito",
- "noShippingOptions": "No hay opciones de envío disponibles para tu dirección"
+ "noShippingOptions": "No hay opciones de envío disponibles para tu dirección",
+ "countryRequired": "País es un campo obligatorio"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
@@ -427,13 +497,24 @@
"button": "Escribe una opinión",
"title": "Escribe una opinión",
"submit": "Enviar",
+ "cancel": "Cancelar",
"ratingLabel": "Calificación",
"titleLabel": "Título",
"reviewLabel": "Revisar",
"nameLabel": "Nombre",
"emailLabel": "Correo electrónico",
"successMessage": "¡Tu reseña fue enviada con éxito!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "titleRequired": "Se requiere título",
+ "authorRequired": "El campo Nombre es obligatorio",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "textRequired": "Es necesario revisar",
+ "ratingRequired": "Se requiere una calificación",
+ "ratingTooSmall": "La puntuación debe ser al menos 1",
+ "ratingTooLarge": "El puntaje debe ser como máximo 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Mantente al día con las últimas noticias y ofertas de nuestra tienda.",
"subscribedToNewsletter": "¡Te suscribiste a nuestro boletín!",
"Errors": {
- "invalidEmail": "Ingrese una dirección de correo electrónico válida.",
+ "emailRequired": "El campo de correo electrónico es obligatorio",
+ "invalidEmail": "Por favor, introduzca una dirección de email válida",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "range": "Precio de {minValue} a {maxValue}."
}
},
"GiftCertificates": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Reconozco que este Certificado de Regalo caducará el {expiryDate}",
"ctaLabel": "Agregar al carrito",
"Errors": {
- "amountRequired": "Seleccione o ingrese el monto de un certificado de regalo.",
- "amountInvalid": "Seleccione un monto de certificado de regalo válido.",
- "amountOutOfRange": "Ingrese una cantidad entre {minAmount} y {maxAmount}.",
- "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde."
+ "amountRequired": "Por favor, selecciona o introduce el importe de un vale regalo",
+ "amountInvalid": "Por favor, seleccione un importe válido de un certificado regalo",
+ "amountOutOfRange": "Por favor, introduzca una cantidad entre {minAmount} y {maxAmount}",
+ "unexpectedSettingsError": "Se produjo un error inesperado al recuperar la configuración del certificado de regalo. Intente de nuevo más tarde.",
+ "senderNameRequired": "Tu nombre es obligatorio",
+ "senderEmailRequired": "Tu correo electrónico es obligatorio",
+ "recipientNameRequired": "Se requiere el nombre del destinatario",
+ "recipientEmailRequired": "Se requiere el email del destinatario",
+ "emailInvalid": "Por favor, introduzca una dirección de email válida",
+ "checkboxRequired": "Debes marcar esta casilla para continuar"
}
}
}
},
"Form": {
- "optional": "Opcional"
+ "optional": "Opcional",
+ "Errors": {
+ "invalidInput": "Por favor, revisa tu opinión y vuelve a intentarlo",
+ "invalidFormat": "El valor introducido no coincide con el formato requerido"
+ }
}
}
diff --git a/core/messages/es.json b/core/messages/es.json
index c21c783f2..507e02c4b 100644
--- a/core/messages/es.json
+++ b/core/messages/es.json
@@ -43,7 +43,17 @@
"newPassword": "Nueva contraseña",
"confirmPassword": "Confirmar contraseña",
"passwordUpdated": "La contraseña se ha actualizado correctamente.",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe tener al menos {minLength, plural, =1 {1 carácter} other {# caracteres}}",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Confirma tu contraseña"
+ }
},
"Login": {
"title": "Iniciar sesión",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"passwordResetRequired": "Es necesario restablecer la contraseña. Consulta tu correo electrónico para recibir instrucciones sobre cómo restablecer tu contraseña.",
"invalidToken": "Tu enlace de inicio de sesión no es válido o ha caducado. Intenta conectarte de nuevo.",
+ "FieldErrors": {
+ "emailRequired": "Se requiere un correo electrónico",
+ "emailInvalid": "Introduce una dirección de correo electrónico válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "invalidInput": "Comprueba lo que has escrito e inténtalo de nuevo."
+ },
"CreateAccount": {
"title": "¿Cliente nuevo?",
"accountBenefits": "Cree una cuenta con nosotros y podrá:",
@@ -70,14 +86,36 @@
"title": "Olvidé mi contraseña",
"subtitle": "Introduce a continuación la dirección de correo electrónico asociada a tu cuenta. Te enviaremos instrucciones para restablecer tu contraseña.",
"confirmResetPassword": "Si la dirección de correo electrónico {email} está vinculada a una cuenta en nuestra tienda, te hemos enviado un correo electrónico de restablecimiento de contraseña. Comprueba tu bandeja de entrada y tu carpeta de correo no deseado si no lo ves.",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "emailRequired": "Se requiere un correo electrónico",
+ "emailInvalid": "Introduce una dirección de correo electrónico válida"
+ }
}
},
"Register": {
"title": "Registrar cuenta",
"heading": "Cuenta nueva",
"cta": "Crear cuenta",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido(s) es obligatorio.",
+ "emailRequired": "Se requiere un correo electrónico",
+ "emailInvalid": "Introduce una dirección de correo electrónico válida",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe tener al menos {minLength, plural, =1 {1 carácter} other {# caracteres}}",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "addressLine1Required": "El campo Línea de dirección 1 es obligatorio",
+ "cityRequired": "El campo Ciudad es obligatorio",
+ "countryRequired": "El campo de país es obligatorio.",
+ "stateRequired": "El campo de Estado/Provincia es obligatorio",
+ "postalCodeRequired": "El campo Código postal es obligatorio"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
"EmptyState": {
"title": "No tienes ninguna dirección"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "lastNameRequired": "El campo Apellido(s) es obligatorio.",
+ "addressLine1Required": "El campo Línea de dirección 1 es obligatorio",
+ "cityRequired": "El campo Ciudad es obligatorio",
+ "countryRequired": "El campo de país es obligatorio.",
+ "stateRequired": "El campo de Estado/Provincia es obligatorio",
+ "postalCodeRequired": "El campo Código postal es obligatorio"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Suscríbase a nuestro boletín.",
"marketingPreferencesUpdated": "¡Las preferencias de marketing se han actualizado correctamente!",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "El campo Nombre es obligatorio.",
+ "firstNameTooSmall": "El nombre debe tener al menos 2 caracteres",
+ "lastNameRequired": "El campo Apellido(s) es obligatorio.",
+ "lastNameTooSmall": "El apellido debe tener al menos 2 caracteres",
+ "emailRequired": "Se requiere un correo electrónico",
+ "emailInvalid": "Introduce una dirección de correo electrónico válida",
+ "currentPasswordRequired": "Es obligatorio indicar la contraseña actual",
+ "passwordRequired": "Se requiere la contraseña",
+ "passwordTooSmall": "La contraseña debe tener al menos {minLength, plural, =1 {1 carácter} other {# caracteres}}",
+ "passwordLowercaseRequired": "La contraseña debe contener al menos una letra minúscula",
+ "passwordUppercaseRequired": "La contraseña debe contener al menos una letra mayúscula",
+ "passwordNumberRequired": "La contraseña debe contener al menos {minNumbers, plural, =1 {un número} other {# números}}",
+ "passwordSpecialCharacterRequired": "La contraseña debe contener al menos un carácter especial",
+ "passwordsMustMatch": "Las contraseñas no coinciden",
+ "confirmPasswordRequired": "Confirma tu contraseña"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Nos hemos dado cuenta de que tenías artículos guardados en un carrito anterior, así que los hemos añadido a tu carrito actual.",
"cartRestored": "Empezaste a llenar un carrito en otro dispositivo y lo hemos restaurado aquí para que puedas seguir donde lo dejaste.",
"cartUpdateInProgress": "Tienes una actualización del carrito en curso. ¿Seguro que quieres abandonar esta página? Es posible que se pierdan los cambios.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "quantityReadyToShip": "{quantity, number} listo para enviar",
+ "quantityOnBackorder": "Cantidad que se añadirá a pedidos pendientes: {quantity, number}",
+ "partiallyAvailable": "Cantidad disponible: {quantity, number}",
"CheckoutSummary": {
"title": "Resumen",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Actualizar envío",
"addShipping": "Añadir envío",
"cartNotFound": "Se ha producido un error al recuperar tu carrito",
- "noShippingOptions": "No hay opciones de envío disponibles para tu dirección"
+ "noShippingOptions": "No hay opciones de envío disponibles para tu dirección",
+ "countryRequired": "El campo de país es obligatorio."
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en existencias",
"backorderQuantity": "{cantidad, número} en pedidos pendientes",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Añadir al carrito",
"outOfStock": "Sin existencias",
@@ -427,13 +497,24 @@
"button": "Escribir una reseña",
"title": "Escribir una reseña",
"submit": "Enviar",
+ "cancel": "Cancelar",
"ratingLabel": "Calificación",
"titleLabel": "Título",
"reviewLabel": "Reseña",
"nameLabel": "Nombre",
"emailLabel": "Correo electrónico",
"successMessage": "¡Tu reseña se ha enviado correctamente!",
- "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
+ "somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde.",
+ "FieldErrors": {
+ "titleRequired": "El título es obligatorio",
+ "authorRequired": "El campo Nombre es obligatorio",
+ "emailRequired": "Se requiere un correo electrónico",
+ "emailInvalid": "Introduce una dirección de correo electrónico válida",
+ "textRequired": "La revisión es obligatoria",
+ "ratingRequired": "La calificación es obligatoria",
+ "ratingTooSmall": "La puntuación debe ser como mínimo 1",
+ "ratingTooLarge": "La puntuación debe ser como máximo 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Entérate de todas las novedades y ofertas de nuestra tienda.",
"subscribedToNewsletter": "¡Te has suscrito a nuestro boletín!",
"Errors": {
- "invalidEmail": "Ingrese una dirección de correo electrónico válida.",
+ "emailRequired": "Se requiere un correo electrónico",
+ "invalidEmail": "Introduce una dirección de correo electrónico válida",
"somethingWentWrong": "Algo salió mal. Vuelva a intentarlo más tarde."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "El precio original era {price}.",
+ "currentPrice": "El precio actual es {price}.",
+ "range": "Precios entre {minValue} y {maxValue}."
}
},
"GiftCertificates": {
@@ -574,7 +656,7 @@
"title": "Verificar saldo",
"description": "Puedes comprobar el saldo y obtener la información sobre tu cupón de regalo escribiendo el código en la casilla de abajo.",
"inputLabel": "Código",
- "inputPlaceholder": "xxx-xxx-xxx-xxx",
+ "inputPlaceholder": "XXX-XXX-XXX-XXX",
"purchasedDateLabel": "Comprado",
"senderLabel": "de",
"Errors": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Reconozco que este vale de regalo caducará el {expiryDate}",
"ctaLabel": "Añadir al carrito",
"Errors": {
- "amountRequired": "Selecciona o introduce el importe de un certificado de regalo.",
- "amountInvalid": "Selecciona un importe de certificado de regalo válido.",
- "amountOutOfRange": "Introduce una cantidad entre {minAmount} y {maxAmount}.",
- "unexpectedSettingsError": "Se ha producido un error inesperado al recuperar la configuración del cupón de regalo. Vuelve a intentarlo más tarde."
+ "amountRequired": "Selecciona o introduce un importe para el cupón de regalo",
+ "amountInvalid": "Selecciona un importe válido para el cupón de regalo",
+ "amountOutOfRange": "Introduce una cantidad entre {minAmount} y {maxAmount}",
+ "unexpectedSettingsError": "Se ha producido un error inesperado al recuperar la configuración del cupón de regalo. Vuelve a intentarlo más tarde.",
+ "senderNameRequired": "Tu nombre es obligatorio",
+ "senderEmailRequired": "Tu correo electrónico es obligatorio",
+ "recipientNameRequired": "El nombre del destinatario es obligatorio",
+ "recipientEmailRequired": "El correo electrónico del destinatario es obligatorio",
+ "emailInvalid": "Introduce una dirección de correo electrónico válida",
+ "checkboxRequired": "Debes marcar esta casilla para continuar"
}
}
}
},
"Form": {
- "optional": "Opcional"
+ "optional": "Opcional",
+ "Errors": {
+ "invalidInput": "Comprueba lo que has escrito e inténtalo de nuevo",
+ "invalidFormat": "El valor introducido no coincide con el formato requerido"
+ }
}
}
diff --git a/core/messages/fr.json b/core/messages/fr.json
index cc1171ace..9e3ba28a7 100644
--- a/core/messages/fr.json
+++ b/core/messages/fr.json
@@ -43,7 +43,17 @@
"newPassword": "Nouveau mot de passe",
"confirmPassword": "Confirmer le mot de passe",
"passwordUpdated": "Le mot de passe a bien été mis à jour !",
- "somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard."
+ "somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard.",
+ "FieldErrors": {
+ "passwordRequired": "Un mot de passe est requis",
+ "passwordTooSmall": "Le mot de passe doit comporter au moins {minLength, plural, =1 {1 character} other {# characters}} caractères",
+ "passwordLowercaseRequired": "Le mot de passe doit comporter au moins une lettre minuscule",
+ "passwordUppercaseRequired": "Le mot de passe doit comporter au moins une lettre majuscule",
+ "passwordNumberRequired": "Le mot de passe doit comporter au moins {minNumbers, plural, =1 {one number} other {# numbers}} chiffres",
+ "passwordSpecialCharacterRequired": "Le mot de passe doit comporter au moins un caractère spécial",
+ "passwordsMustMatch": "Les mots de passe ne correspondent pas",
+ "confirmPasswordRequired": "Veuillez confirmer votre mot de passe"
+ }
},
"Login": {
"title": "Connexion",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard.",
"passwordResetRequired": "Réinitialisation du mot de passe requise. Veuillez consulter votre e-mail pour les instructions de réinitialisation de votre mot de passe.",
"invalidToken": "Votre lien de connexion n'est pas valide ou a expiré. Veuillez réessayer de vous connecter.",
+ "FieldErrors": {
+ "emailRequired": "L'adresse e-mail est requise",
+ "emailInvalid": "Veuillez saisir une adresse e-mail valide",
+ "passwordRequired": "Un mot de passe est requis",
+ "invalidInput": "Veuillez vérifier votre saisie et réessayer."
+ },
"CreateAccount": {
"title": "Nouveau client ?",
"accountBenefits": "Créez un compte sur notre site et vous pourrez :",
@@ -70,14 +86,36 @@
"title": "Mot de passe oublié",
"subtitle": "Veuillez saisir ci-dessous l'adresse e-mail associée à votre compte. Nous vous enverrons des instructions pour réinitialiser votre mot de passe.",
"confirmResetPassword": "Si l'adresse e-mail {email} est liée à un compte dans notre boutique, vous recevrez un e-mail pour réinitialiser votre mot de passe. Veuillez consulter votre boîte de réception, ainsi que votre dossier de courrier indésirable si vous ne trouvez pas cet e-mail.",
- "somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard."
+ "somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard.",
+ "FieldErrors": {
+ "emailRequired": "L'adresse e-mail est requise",
+ "emailInvalid": "Veuillez saisir une adresse e-mail valide"
+ }
}
},
"Register": {
"title": "Enregistrer un compte",
"heading": "Nouveau compte",
"cta": "Créer un compte",
- "somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard."
+ "somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard.",
+ "FieldErrors": {
+ "firstNameRequired": "Le prénom est requis",
+ "lastNameRequired": "Le nom de famille est requis",
+ "emailRequired": "L'adresse e-mail est requise",
+ "emailInvalid": "Veuillez saisir une adresse e-mail valide",
+ "passwordRequired": "Un mot de passe est requis",
+ "passwordTooSmall": "Le mot de passe doit comporter au moins {minLength, plural, =1 {1 character} other {# characters}} caractères",
+ "passwordLowercaseRequired": "Le mot de passe doit comporter au moins une lettre minuscule",
+ "passwordUppercaseRequired": "Le mot de passe doit comporter au moins une lettre majuscule",
+ "passwordNumberRequired": "Le mot de passe doit comporter au moins {minNumbers, plural, =1 {one number} other {# numbers}} chiffres",
+ "passwordSpecialCharacterRequired": "Le mot de passe doit comporter au moins un caractère spécial",
+ "passwordsMustMatch": "Les mots de passe ne correspondent pas",
+ "addressLine1Required": "Ligne d'adresse 1 est requise",
+ "cityRequired": "La ville est requise",
+ "countryRequired": "Le pays est requis",
+ "stateRequired": "État/province est requis",
+ "postalCodeRequired": "Le code postal est requis"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard.",
"EmptyState": {
"title": "Vous n'avez pas d'adresse"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Le prénom est requis",
+ "lastNameRequired": "Le nom de famille est requis",
+ "addressLine1Required": "Ligne d'adresse 1 est requise",
+ "cityRequired": "La ville est requise",
+ "countryRequired": "Le pays est requis",
+ "stateRequired": "État/province est requis",
+ "postalCodeRequired": "Le code postal est requis"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Abonnez-vous à notre newsletter.",
"marketingPreferencesUpdated": "Les préférences marketing ont bien été mises à jour.",
"somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Le prénom est requis",
+ "firstNameTooSmall": "Le prénom doit comporter au moins 2 caractères",
+ "lastNameRequired": "Le nom de famille est requis",
+ "lastNameTooSmall": "Le nom de famille doit comporter au moins 2 caractères",
+ "emailRequired": "L'adresse e-mail est requise",
+ "emailInvalid": "Veuillez saisir une adresse e-mail valide",
+ "currentPasswordRequired": "Vous devez saisir le mot de passe actuel",
+ "passwordRequired": "Un mot de passe est requis",
+ "passwordTooSmall": "Le mot de passe doit comporter au moins {minLength, plural, =1 {1 character} other {# characters}} caractères",
+ "passwordLowercaseRequired": "Le mot de passe doit comporter au moins une lettre minuscule",
+ "passwordUppercaseRequired": "Le mot de passe doit comporter au moins une lettre majuscule",
+ "passwordNumberRequired": "Le mot de passe doit comporter au moins {minNumbers, plural, =1 {one number} other {# numbers}} chiffres",
+ "passwordSpecialCharacterRequired": "Le mot de passe doit comporter au moins un caractère spécial",
+ "passwordsMustMatch": "Les mots de passe ne correspondent pas",
+ "confirmPasswordRequired": "Veuillez confirmer votre mot de passe"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Nous avons remarqué que votre panier précédent contenait des articles enregistrés. Nous avons donc ajouté ces articles à votre panier actuel.",
"cartRestored": "Vous avez débuté vos achats sur un autre appareil. Nous avons restauré votre panier ici pour que vous puissiez reprendre là où vous en étiez.",
"cartUpdateInProgress": "Une mise à jour de votre panier est en cours. Voulez-vous vraiment quitter cette page ? Vos modifications pourraient être perdues.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "Le prix initial était de {price}.",
+ "currentPrice": "Le prix actuel est de {price}.",
+ "quantityReadyToShip": "{quantity, number} prêts à être expédiés",
+ "quantityOnBackorder": "{quantity, number} seront en attente de réapprovisionnement",
+ "partiallyAvailable": "Seulement {quantity, number} disponibles",
"CheckoutSummary": {
"title": "Récapitulatif",
"subTotal": "Sous-total",
@@ -335,7 +402,8 @@
"updateShipping": "Mettre à jour l’expédition",
"addShipping": "Ajouter l’expédition",
"cartNotFound": "Une erreur s’est produite lors de la récupération de votre panier",
- "noShippingOptions": "Aucune option de livraison n'est disponible pour votre adresse"
+ "noShippingOptions": "Aucune option de livraison n'est disponible pour votre adresse",
+ "countryRequired": "Le pays est requis"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Informations supplémentaires",
"currentStock": "{quantity, number} en stock",
"backorderQuantity": "{quantité, nombre} en attente de réapprovisionnement",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Ajouter au panier",
"outOfStock": "En rupture de stock",
@@ -427,13 +497,24 @@
"button": "Rédiger un avis",
"title": "Rédiger un avis",
"submit": "Envoyer",
+ "cancel": "Annuler",
"ratingLabel": "Note",
"titleLabel": "Titre",
"reviewLabel": "Avis",
"nameLabel": "Nom",
"emailLabel": "E-mail",
"successMessage": "Votre avis a bien été envoyé !",
- "somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard."
+ "somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard.",
+ "FieldErrors": {
+ "titleRequired": "Le titre est obligatoire",
+ "authorRequired": "Le nom doit être renseigné",
+ "emailRequired": "L'adresse e-mail est requise",
+ "emailInvalid": "Veuillez saisir une adresse e-mail valide",
+ "textRequired": "Une révision est requise",
+ "ratingRequired": "La note est requise",
+ "ratingTooSmall": "La note doit être supérieure ou égale à 1",
+ "ratingTooLarge": "La note doit être au maximum de 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Restez informé des dernières nouvelles et offres de notre magasin.",
"subscribedToNewsletter": "Votre abonnement à la newsletter a bien été pris en compte !",
"Errors": {
- "invalidEmail": "Veuillez saisir une adresse e-mail valide.",
+ "emailRequired": "L'adresse e-mail est requise",
+ "invalidEmail": "Veuillez saisir une adresse e-mail valide",
"somethingWentWrong": "Une erreur s'est produite. Veuillez réessayer plus tard."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "Le prix initial était de {price}.",
+ "currentPrice": "Le prix actuel est de {price}.",
+ "range": "Prix de {minValue} à {maxValue}."
}
},
"GiftCertificates": {
@@ -574,7 +656,7 @@
"title": "Vérifier le solde",
"description": "Vous pouvez vérifier le solde et obtenir des informations sur votre chèque-cadeau en saisissant le code dans la case ci-dessous.",
"inputLabel": "Code",
- "inputPlaceholder": "xxx-xxx-xxx-xxx",
+ "inputPlaceholder": "XXX-XXX-XXX-XXX",
"purchasedDateLabel": "Acheté(s",
"senderLabel": "De",
"Errors": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Je reconnais que ce chèque-cadeau expirera le {expiryDate}",
"ctaLabel": "Ajouter au panier",
"Errors": {
- "amountRequired": "Veuillez sélectionner ou saisir un montant de chèque-cadeau.",
- "amountInvalid": "Veuillez sélectionner un montant de chèque-cadeau valide.",
- "amountOutOfRange": "Veuillez saisir un montant entre {minAmount} et {maxAmount}.",
- "unexpectedSettingsError": "Une erreur inattendue s’est produite lors de la récupération des paramètres du chèque-cadeau. Veuillez réessayer plus tard."
+ "amountRequired": "Veuillez sélectionner ou saisir un montant de chèque-cadeau",
+ "amountInvalid": "Veuillez sélectionner un montant de chèque-cadeau valide",
+ "amountOutOfRange": "Veuillez saisir un montant entre {minAmount} et {maxAmount}",
+ "unexpectedSettingsError": "Une erreur inattendue s’est produite lors de la récupération des paramètres du chèque-cadeau. Veuillez réessayer plus tard.",
+ "senderNameRequired": "Votre nom est requis",
+ "senderEmailRequired": "Votre adresse e-mail est requise",
+ "recipientNameRequired": "Le nom du destinataire est obligatoire",
+ "recipientEmailRequired": "L’adresse e-mail du destinataire est obligatoire",
+ "emailInvalid": "Veuillez saisir une adresse e-mail valide",
+ "checkboxRequired": "Vous devez cocher cette case pour continuer"
}
}
}
},
"Form": {
- "optional": "facultatif"
+ "optional": "facultatif",
+ "Errors": {
+ "invalidInput": "Veuillez vérifier votre saisie et réessayer",
+ "invalidFormat": "La valeur saisie ne correspond pas au format requis"
+ }
}
}
diff --git a/core/messages/it.json b/core/messages/it.json
index 3f319e845..9d49e830c 100644
--- a/core/messages/it.json
+++ b/core/messages/it.json
@@ -43,7 +43,17 @@
"newPassword": "Nuova password",
"confirmPassword": "Conferma password",
"passwordUpdated": "La password è stata aggiornata!",
- "somethingWentWrong": "Si è verificato un errore. Riprova più tardi."
+ "somethingWentWrong": "Si è verificato un errore. Riprova più tardi.",
+ "FieldErrors": {
+ "passwordRequired": "La password è obbligatoria",
+ "passwordTooSmall": "La password deve essere lunga almeno {minLength, plural, =1 {1 carattere} other {# caratteri}}",
+ "passwordLowercaseRequired": "La password deve contenere almeno una lettera minuscola",
+ "passwordUppercaseRequired": "La password deve contenere almeno una lettera maiuscola",
+ "passwordNumberRequired": "La password deve contenere almeno {minNumbers, plural, =1 {un numero} other {# numeri}}",
+ "passwordSpecialCharacterRequired": "La password deve contenere almeno un carattere speciale",
+ "passwordsMustMatch": "Le password non corrispondono",
+ "confirmPasswordRequired": "Conferma la tua password"
+ }
},
"Login": {
"title": "Accedi",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Si è verificato un errore. Riprova più tardi.",
"passwordResetRequired": "È necessario reimpostare la password. Controlla la tua email per le istruzioni su come reimpostare la password.",
"invalidToken": "Il tuo link di accesso non è valido o è scaduto. Riprova ad accedere.",
+ "FieldErrors": {
+ "emailRequired": "L'indirizzo email è obbligatorio",
+ "emailInvalid": "Inserisci un indirizzo e-mail valido",
+ "passwordRequired": "La password è obbligatoria",
+ "invalidInput": "Controlla i dati inseriti e riprova."
+ },
"CreateAccount": {
"title": "Nuovo cliente?",
"accountBenefits": "Crea un account con noi e sarai in grado di:",
@@ -70,14 +86,36 @@
"title": "Password dimenticata",
"subtitle": "Inserisci di seguito l'e-mail associata al tuo account. Ti invieremo le istruzioni per reimpostare la password.",
"confirmResetPassword": "Se l'indirizzo e-mail {email} è collegato a un account nel nostro negozio, ti abbiamo inviato un'e-mail per reimpostare la password. Se non la trovi, controlla le cartelle di posta in arrivo e indesiderata.",
- "somethingWentWrong": "Si è verificato un errore. Riprova più tardi."
+ "somethingWentWrong": "Si è verificato un errore. Riprova più tardi.",
+ "FieldErrors": {
+ "emailRequired": "L'indirizzo email è obbligatorio",
+ "emailInvalid": "Inserisci un indirizzo e-mail valido"
+ }
}
},
"Register": {
"title": "Registra un account",
"heading": "Nuovo account",
"cta": "Crea account",
- "somethingWentWrong": "Si è verificato un errore. Riprova più tardi."
+ "somethingWentWrong": "Si è verificato un errore. Riprova più tardi.",
+ "FieldErrors": {
+ "firstNameRequired": "Il nome è obbligatorio",
+ "lastNameRequired": "Il cognome è obbligatorio",
+ "emailRequired": "L'indirizzo email è obbligatorio",
+ "emailInvalid": "Inserisci un indirizzo e-mail valido",
+ "passwordRequired": "La password è obbligatoria",
+ "passwordTooSmall": "La password deve essere lunga almeno {minLength, plural, =1 {1 carattere} other {# caratteri}}",
+ "passwordLowercaseRequired": "La password deve contenere almeno una lettera minuscola",
+ "passwordUppercaseRequired": "La password deve contenere almeno una lettera maiuscola",
+ "passwordNumberRequired": "La password deve contenere almeno {minNumbers, plural, =1 {un numero} other {# numeri}}",
+ "passwordSpecialCharacterRequired": "La password deve contenere almeno un carattere speciale",
+ "passwordsMustMatch": "Le password non corrispondono",
+ "addressLine1Required": "La riga 1 dell'indirizzo è obbligatoria",
+ "cityRequired": "La Città è necessaria",
+ "countryRequired": "Il paese è obbligatorio",
+ "stateRequired": "Lo Stato/Provincia è obbligatorio",
+ "postalCodeRequired": "Il CAP è necessario"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Si è verificato un errore. Riprova più tardi.",
"EmptyState": {
"title": "Non hai indirizzi"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Il nome è obbligatorio",
+ "lastNameRequired": "Il cognome è obbligatorio",
+ "addressLine1Required": "La riga 1 dell'indirizzo è obbligatoria",
+ "cityRequired": "La Città è necessaria",
+ "countryRequired": "Il paese è obbligatorio",
+ "stateRequired": "Lo Stato/Provincia è obbligatorio",
+ "postalCodeRequired": "Il CAP è necessario"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Iscriviti alla nostra newsletter.",
"marketingPreferencesUpdated": "Le preferenze di marketing sono state aggiornate.",
"somethingWentWrong": "Si è verificato un errore. Riprova più tardi."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Il nome è obbligatorio",
+ "firstNameTooSmall": "Il nome deve essere lungo almeno 2 caratteri",
+ "lastNameRequired": "Il cognome è obbligatorio",
+ "lastNameTooSmall": "Il cognome deve essere lungo almeno 2 caratteri",
+ "emailRequired": "L'indirizzo email è obbligatorio",
+ "emailInvalid": "Inserisci un indirizzo e-mail valido",
+ "currentPasswordRequired": "È necessario inserire la password attuale",
+ "passwordRequired": "La password è obbligatoria",
+ "passwordTooSmall": "La password deve essere lunga almeno {minLength, plural, =1 {1 carattere} other {# caratteri}}",
+ "passwordLowercaseRequired": "La password deve contenere almeno una lettera minuscola",
+ "passwordUppercaseRequired": "La password deve contenere almeno una lettera maiuscola",
+ "passwordNumberRequired": "La password deve contenere almeno {minNumbers, plural, =1 {un numero} other {# numeri}}",
+ "passwordSpecialCharacterRequired": "La password deve contenere almeno un carattere speciale",
+ "passwordsMustMatch": "Le password non corrispondono",
+ "confirmPasswordRequired": "Conferma la tua password"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Abbiamo notato che avevi salvato degli articoli in un carrello precedente, quindi li abbiamo aggiunti al carrello attuale.",
"cartRestored": "Hai avviato un carrello su un altro dispositivo e lo abbiamo ripristinato qui, così puoi riprendere da dove avevi lasciato.",
"cartUpdateInProgress": "Hai un aggiornamento del carrello attivo in corso. Uscire dalla pagina? Le modifiche potrebbero andare perse.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "Il prezzo originale era {price}.",
+ "currentPrice": "Il prezzo corrente è {price}.",
+ "quantityReadyToShip": "{quantity, number} pronto per la spedizione",
+ "quantityOnBackorder": "{quantity, number} sarà in arretrato",
+ "partiallyAvailable": "Solo {quantity, number} disponibili",
"CheckoutSummary": {
"title": "Riepilogo",
"subTotal": "Subtotale",
@@ -335,7 +402,8 @@
"updateShipping": "Aggiorna la spedizione",
"addShipping": "Aggiungi spedizione",
"cartNotFound": "Si è verificato un errore durante il recupero del carrello",
- "noShippingOptions": "Non ci sono opzioni di spedizione disponibili per il tuo indirizzo"
+ "noShippingOptions": "Non ci sono opzioni di spedizione disponibili per il tuo indirizzo",
+ "countryRequired": "Il paese è obbligatorio"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Informazioni aggiuntive",
"currentStock": "{quantità, numero} in magazzino",
"backorderQuantity": "{quantity, number} sarà in arretrato",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Aggiungi al carrello",
"outOfStock": "Esaurito",
@@ -427,13 +497,24 @@
"button": "Scrivi una recensione",
"title": "Scrivi una recensione",
"submit": "Invia",
+ "cancel": "Annulla",
"ratingLabel": "Valutazione",
"titleLabel": "Titolo",
"reviewLabel": "Recensione",
"nameLabel": "Nome",
"emailLabel": "E-mail",
"successMessage": "La tua recensione è stata inviata correttamente.",
- "somethingWentWrong": "Si è verificato un errore. Riprova più tardi."
+ "somethingWentWrong": "Si è verificato un errore. Riprova più tardi.",
+ "FieldErrors": {
+ "titleRequired": "Il titolo è obbligatorio",
+ "authorRequired": "Il nome è obbligatorio",
+ "emailRequired": "L'indirizzo email è obbligatorio",
+ "emailInvalid": "Inserisci un indirizzo e-mail valido",
+ "textRequired": "La revisione è obbligatoria",
+ "ratingRequired": "La valutazione è obbligatoria",
+ "ratingTooSmall": "Il punteggio deve essere almeno 1",
+ "ratingTooLarge": "Il punteggio deve essere al massimo 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Ricevi aggiornamenti sulle ultime novità e offerte dal nostro negozio.",
"subscribedToNewsletter": "Hai effettuato l'iscrizione alla nostra newsletter.",
"Errors": {
- "invalidEmail": "Inserisci un indirizzo e-mail valido.",
+ "emailRequired": "L'indirizzo email è obbligatorio",
+ "invalidEmail": "Inserisci un indirizzo e-mail valido",
"somethingWentWrong": "Si è verificato un errore. Riprova più tardi."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "Il prezzo originale era {price}.",
+ "currentPrice": "Il prezzo corrente è {price}.",
+ "range": "Prezzo da {minValue} a {maxValue}."
}
},
"GiftCertificates": {
@@ -574,7 +656,7 @@
"title": "Controlla il saldo",
"description": "Puoi controllare il saldo e ottenere informazioni sul tuo buono regalo inserendo il codice nella casella sottostante.",
"inputLabel": "Codice",
- "inputPlaceholder": "xxx-xxx-xxx-xxx",
+ "inputPlaceholder": "XXX-XXX-XXX-XXX",
"purchasedDateLabel": "Acquistato",
"senderLabel": "Da",
"Errors": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Riconosco che questo buono regalo scadrà il {expiryDate}",
"ctaLabel": "Aggiungi al carrello",
"Errors": {
- "amountRequired": "Seleziona o inserisci un importo del buono regalo.",
- "amountInvalid": "Seleziona un importo valido per il buono regalo.",
- "amountOutOfRange": "Inserisci un importo compreso tra {minAmount} e {maxAmount}.",
- "unexpectedSettingsError": "Si è verificato un errore imprevisto durante il recupero delle impostazioni del buono regalo. Riprova più tardi."
+ "amountRequired": "Seleziona o inserisci un importo del buono regalo",
+ "amountInvalid": "Seleziona un importo valido per il buono regalo",
+ "amountOutOfRange": "Inserisci un importo compreso tra {minAmount} e {maxAmount}",
+ "unexpectedSettingsError": "Si è verificato un errore imprevisto durante il recupero delle impostazioni del buono regalo. Riprova più tardi.",
+ "senderNameRequired": "Il tuo nome è obbligatorio",
+ "senderEmailRequired": "La tua e-mail è obbligatoria",
+ "recipientNameRequired": "Il nome del destinatario è obbligatorio",
+ "recipientEmailRequired": "L'e-mail del destinatario è obbligatoria",
+ "emailInvalid": "Inserisci un indirizzo e-mail valido",
+ "checkboxRequired": "Devi spuntare questa casella per continuare"
}
}
}
},
"Form": {
- "optional": "facoltativo"
+ "optional": "facoltativo",
+ "Errors": {
+ "invalidInput": "Controlla i dati inseriti e riprova",
+ "invalidFormat": "Il valore inserito non corrisponde al formato richiesto"
+ }
}
}
diff --git a/core/messages/ja.json b/core/messages/ja.json
index 08ae0cd1b..ff94c4325 100644
--- a/core/messages/ja.json
+++ b/core/messages/ja.json
@@ -43,7 +43,17 @@
"newPassword": "新しいパスワード",
"confirmPassword": "パスワード確認",
"passwordUpdated": "パスワードが正常に更新されました!",
- "somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。"
+ "somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。",
+ "FieldErrors": {
+ "passwordRequired": "パスワードが必要です",
+ "passwordTooSmall": "パスワードは少なくとも {minLength, plural, =1 {1 character } other {# characters }}の長さである必要があります",
+ "passwordLowercaseRequired": "パスワードには少なくとも1つの小文字を含める必要があります",
+ "passwordUppercaseRequired": "パスワードには少なくとも1つの大文字を含める必要があります",
+ "passwordNumberRequired": "パスワードには少なくとも {minNumbers, plural, =1 {one number } other {#個の数字}}が含まれている必要があります",
+ "passwordSpecialCharacterRequired": "パスワードには少なくとも1つの特殊文字を含める必要があります",
+ "passwordsMustMatch": "パスワードが一致しません",
+ "confirmPasswordRequired": "パスワードを確認してください"
+ }
},
"Login": {
"title": "ログイン",
@@ -56,6 +66,12 @@
"somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。",
"passwordResetRequired": "パスワードのリセットが必要です。パスワードをリセットするための手順については、メールを確認してください。",
"invalidToken": "ログインリンクが無効または期限切れです。もう一度ログインしてください。",
+ "FieldErrors": {
+ "emailRequired": "メールアドレスは必須です",
+ "emailInvalid": "有効なメールアドレスを入力してください",
+ "passwordRequired": "パスワードが必要です",
+ "invalidInput": "入力内容を確認して、もう一度お試しください。"
+ },
"CreateAccount": {
"title": "新規のお客様ですか?",
"accountBenefits": "アカウントを作成すると、次のことができるようになります:",
@@ -70,14 +86,36 @@
"title": "パスワードをお忘れですか",
"subtitle": "アカウントに関連付けられたメールアドレスを以下に入力してください。パスワードをリセットするための手順をお送りいたします。",
"confirmResetPassword": "メールアドレス {email} が当社のアカウントにリンクされている場合、パスワードリセットのメールが送信されました。受信トレイをご確認ください。見つからない場合は、スパムフォルダもご確認ください。",
- "somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。"
+ "somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。",
+ "FieldErrors": {
+ "emailRequired": "メールアドレスは必須です",
+ "emailInvalid": "有効なメールアドレスを入力してください"
+ }
}
},
"Register": {
"title": "アカウントを登録",
"heading": "新しいアカウント",
"cta": "アカウント作成",
- "somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。"
+ "somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。",
+ "FieldErrors": {
+ "firstNameRequired": "名は必須です",
+ "lastNameRequired": "姓は必須です",
+ "emailRequired": "メールアドレスは必須です",
+ "emailInvalid": "有効なメールアドレスを入力してください",
+ "passwordRequired": "パスワードが必要です",
+ "passwordTooSmall": "パスワードは少なくとも {minLength, plural, =1 {1 character } other {# characters }}の長さである必要があります",
+ "passwordLowercaseRequired": "パスワードには少なくとも1つの小文字を含める必要があります",
+ "passwordUppercaseRequired": "パスワードには少なくとも1つの大文字を含める必要があります",
+ "passwordNumberRequired": "パスワードには少なくとも {minNumbers, plural, =1 {one number } other {#個の数字}}が含まれている必要があります",
+ "passwordSpecialCharacterRequired": "パスワードには少なくとも1つの特殊文字を含める必要があります",
+ "passwordsMustMatch": "パスワードが一致しません",
+ "addressLine1Required": "住所1行目は必須です",
+ "cityRequired": "市区町村が必要です",
+ "countryRequired": "国名コードが必要です",
+ "stateRequired": "都道府県が必要です",
+ "postalCodeRequired": "郵便番号は必要です"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。",
"EmptyState": {
"title": "アドレスがありません"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "名は必須です",
+ "lastNameRequired": "姓は必須です",
+ "addressLine1Required": "住所1行目は必須です",
+ "cityRequired": "市区町村が必要です",
+ "countryRequired": "国名コードが必要です",
+ "stateRequired": "都道府県が必要です",
+ "postalCodeRequired": "郵便番号は必要です"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "ニュースレターに登録してください。",
"marketingPreferencesUpdated": "マーケティング設定が正常に更新されました。",
"somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "名は必須です",
+ "firstNameTooSmall": "名は2文字以上でなければなりません",
+ "lastNameRequired": "姓は必須です",
+ "lastNameTooSmall": "姓は2文字以上でなければなりません",
+ "emailRequired": "メールアドレスは必須です",
+ "emailInvalid": "有効なメールアドレスを入力してください",
+ "currentPasswordRequired": "現在のパスワードは必須です",
+ "passwordRequired": "パスワードが必要です",
+ "passwordTooSmall": "パスワードは少なくとも {minLength, plural, =1 {1 character } other {# characters }}の長さである必要があります",
+ "passwordLowercaseRequired": "パスワードには少なくとも1つの小文字を含める必要があります",
+ "passwordUppercaseRequired": "パスワードには少なくとも1つの大文字を含める必要があります",
+ "passwordNumberRequired": "パスワードには少なくとも {minNumbers, plural, =1 {one number } other {#個の数字}}が含まれている必要があります",
+ "passwordSpecialCharacterRequired": "パスワードには少なくとも1つの特殊文字を含める必要があります",
+ "passwordsMustMatch": "パスワードが一致しません",
+ "confirmPasswordRequired": "パスワードを確認してください"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "以前のカートに商品が保存されていたので、それを現在のカートに追加しました。",
"cartRestored": "別のデバイスでカートに商品が追加されていたため、中断されたところからお買い物を再開できるよう、こちらにカートの内容を復元しました。",
"cartUpdateInProgress": "カートの更新が進行中です。このページを離れてもよろしいですか?変更内容が失われる可能性があります。",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "元の価格は{price}でした。",
+ "currentPrice": "現在の価格は{price}です。",
+ "quantityReadyToShip": "{quantity, number} 個、発送準備完了",
+ "quantityOnBackorder": "{quantity, number} はバックオーダーになります",
+ "partiallyAvailable": "{quantity, number} 個のみ在庫あり",
"CheckoutSummary": {
"title": "要約",
"subTotal": "小計",
@@ -335,7 +402,8 @@
"updateShipping": "配送情報を更新",
"addShipping": "配送を追加",
"cartNotFound": "カートの取得中にエラーが発生しました",
- "noShippingOptions": "ご指定の住所で利用できる配送オプションはありません"
+ "noShippingOptions": "ご指定の住所で利用できる配送オプションはありません",
+ "countryRequired": "国名コードが必要です"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "追加情報",
"currentStock": "{quantity, number} 個の在庫あり",
"backorderQuantity": "{quantity, number} はバックオーダーになります",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "カートに追加",
"outOfStock": "品切れ",
@@ -427,13 +497,24 @@
"button": "レビューを書く",
"title": "レビューを書く",
"submit": "提出",
+ "cancel": "キャンセル",
"ratingLabel": "評価",
"titleLabel": "タイトル",
"reviewLabel": "レビュー",
"nameLabel": "名前",
"emailLabel": "Eメール",
"successMessage": "レビューは正常に送信されました。",
- "somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。"
+ "somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。",
+ "FieldErrors": {
+ "titleRequired": "タイトルは必須です",
+ "authorRequired": "商品名は必須です",
+ "emailRequired": "メールアドレスは必須です",
+ "emailInvalid": "有効なメールアドレスを入力してください",
+ "textRequired": "レビューが必要です",
+ "ratingRequired": "評価は必須です",
+ "ratingTooSmall": "評価は1以上である必要があります",
+ "ratingTooLarge": "評価は5以下でなければなりません"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "当店の最新ニュースやオファーをぜひチェックしてください。",
"subscribedToNewsletter": "ニュースレターを購読されました。",
"Errors": {
- "invalidEmail": "有効なメールアドレスを入力してください。",
+ "emailRequired": "メールアドレスは必須です",
+ "invalidEmail": "有効なメールアドレスを入力してください",
"somethingWentWrong": "何か問題が発生しました。後でもう一度やり直してください。"
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "元の価格は{price}でした。",
+ "currentPrice": "現在の価格は{price}です。",
+ "range": "価格は{minValue}から{maxValue}までです。"
}
},
"GiftCertificates": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "このギフト券は{expiryDate}に有効期限が切れることに同意します。",
"ctaLabel": "カートに追加",
"Errors": {
- "amountRequired": "ギフト券の金額を選択または入力してください。",
- "amountInvalid": "有効なギフト券の金額を選択してください。",
- "amountOutOfRange": "{minAmount}から{maxAmount}の間の金額を入力してください。",
- "unexpectedSettingsError": "ギフト券設定の取得中に予期しないエラーが発生しました。しばらくしてから再度お試しください"
+ "amountRequired": "ギフト券の金額を選択または入力してください",
+ "amountInvalid": "有効なギフト券の金額を選択してください",
+ "amountOutOfRange": "{minAmount}から{maxAmount}の間の金額を入力してください",
+ "unexpectedSettingsError": "ギフト券設定の取得中に予期しないエラーが発生しました。しばらくしてから再度お試しください",
+ "senderNameRequired": "お名前は必須です",
+ "senderEmailRequired": "メールアドレスは必須です",
+ "recipientNameRequired": "受取人の名前は必須です",
+ "recipientEmailRequired": "受信者のメールアドレスは必須です",
+ "emailInvalid": "有効なメールアドレスを入力してください",
+ "checkboxRequired": "続行するにはこのボックスにチェックを入れてください"
}
}
}
},
"Form": {
- "optional": "オプション"
+ "optional": "オプション",
+ "Errors": {
+ "invalidInput": "入力内容を確認してもう一度お試しください",
+ "invalidFormat": "入力された値は必要な形式と一致しません"
+ }
}
}
diff --git a/core/messages/nl.json b/core/messages/nl.json
index 99a55d121..fc30faaa6 100644
--- a/core/messages/nl.json
+++ b/core/messages/nl.json
@@ -43,7 +43,17 @@
"newPassword": "Nieuw wachtwoord",
"confirmPassword": "Wachtwoord bevestigen",
"passwordUpdated": "Wachtwoord is succesvol bijgewerkt!",
- "somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw."
+ "somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw.",
+ "FieldErrors": {
+ "passwordRequired": "Wachtwoord is vereist",
+ "passwordTooSmall": "Het wachtwoord moet minimaal {minLength, plural, =1 {1 teken} other {# tekens}} lang zijn",
+ "passwordLowercaseRequired": "Het wachtwoord moet minstens één kleine letter bevatten",
+ "passwordUppercaseRequired": "Het wachtwoord moet minimaal één hoofdletter bevatten",
+ "passwordNumberRequired": "Het wachtwoord moet minimaal {minNumbers, plural, =1 {één cijfer} other {# cijfers}} bevatten",
+ "passwordSpecialCharacterRequired": "Het wachtwoord moet minimaal één speciaal teken bevatten",
+ "passwordsMustMatch": "De wachtwoorden komen niet overeen",
+ "confirmPasswordRequired": "Bevestig je wachtwoord"
+ }
},
"Login": {
"title": "Inloggen",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw.",
"passwordResetRequired": "Wachtwoord opnieuw instellen is vereist. Controleer uw e-mail voor instructies om uw wachtwoord opnieuw in te stellen.",
"invalidToken": "Je aanmeldingslink is ongeldig of verlopen. Probeer opnieuw in te loggen.",
+ "FieldErrors": {
+ "emailRequired": "E-mailadres is vereist",
+ "emailInvalid": "Voer een geldig e-mailadres in",
+ "passwordRequired": "Wachtwoord is vereist",
+ "invalidInput": "Controleer uw invoer en probeer het opnieuw."
+ },
"CreateAccount": {
"title": "Nieuwe klant?",
"accountBenefits": "Maak een account aan bij ons om:",
@@ -70,14 +86,36 @@
"title": "Wachtwoord vergeten",
"subtitle": "Voer hieronder het e-mailadres in dat aan je account is gekoppeld. We sturen je instructies om je wachtwoord opnieuw in te stellen.",
"confirmResetPassword": "Als het e-mailadres {email} is gekoppeld aan een account in onze winkel, hebben we je een e-mail gestuurd om je wachtwoord opnieuw in te stellen. Controleer je inbox en spammap als je de e-mail niet ziet.",
- "somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw."
+ "somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw.",
+ "FieldErrors": {
+ "emailRequired": "E-mailadres is vereist",
+ "emailInvalid": "Voer een geldig e-mailadres in"
+ }
}
},
"Register": {
"title": "Account registreren",
"heading": "Nieuw account",
"cta": "Account aanmaken",
- "somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw."
+ "somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw.",
+ "FieldErrors": {
+ "firstNameRequired": "Voornaam is vereist",
+ "lastNameRequired": "Achternaam is vereist",
+ "emailRequired": "E-mailadres is vereist",
+ "emailInvalid": "Voer een geldig e-mailadres in",
+ "passwordRequired": "Wachtwoord is vereist",
+ "passwordTooSmall": "Het wachtwoord moet minimaal {minLength, plural, =1 {1 teken} other {# tekens}} lang zijn",
+ "passwordLowercaseRequired": "Het wachtwoord moet minstens één kleine letter bevatten",
+ "passwordUppercaseRequired": "Het wachtwoord moet minimaal één hoofdletter bevatten",
+ "passwordNumberRequired": "Het wachtwoord moet minimaal {minNumbers, plural, =1 {één cijfer} other {# cijfers}} bevatten",
+ "passwordSpecialCharacterRequired": "Het wachtwoord moet minimaal één speciaal teken bevatten",
+ "passwordsMustMatch": "De wachtwoorden komen niet overeen",
+ "addressLine1Required": "Adresregel 1 is vereist",
+ "cityRequired": "Plaats is vereist",
+ "countryRequired": "Land is vereist",
+ "stateRequired": "Staat/provincie is vereist",
+ "postalCodeRequired": "Postcode is vereist"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw.",
"EmptyState": {
"title": "Je hebt geen adressen"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Voornaam is vereist",
+ "lastNameRequired": "Achternaam is vereist",
+ "addressLine1Required": "Adresregel 1 is vereist",
+ "cityRequired": "Plaats is vereist",
+ "countryRequired": "Land is vereist",
+ "stateRequired": "Staat/provincie is vereist",
+ "postalCodeRequired": "Postcode is vereist"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Meld u aan voor onze nieuwsbrief.",
"marketingPreferencesUpdated": "Marketingvoorkeuren zijn bijgewerkt!",
"somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Voornaam is vereist",
+ "firstNameTooSmall": "De voornaam moet minimaal 2 tekens lang zijn",
+ "lastNameRequired": "Achternaam is vereist",
+ "lastNameTooSmall": "De achternaam moet minimaal 2 tekens lang zijn",
+ "emailRequired": "E-mailadres is vereist",
+ "emailInvalid": "Voer een geldig e-mailadres in",
+ "currentPasswordRequired": "Huidig wachtwoord is vereist",
+ "passwordRequired": "Wachtwoord is vereist",
+ "passwordTooSmall": "Het wachtwoord moet minimaal {minLength, plural, =1 {1 teken} other {# tekens}} lang zijn",
+ "passwordLowercaseRequired": "Het wachtwoord moet minstens één kleine letter bevatten",
+ "passwordUppercaseRequired": "Het wachtwoord moet minimaal één hoofdletter bevatten",
+ "passwordNumberRequired": "Het wachtwoord moet minimaal {minNumbers, plural, =1 {één cijfer} other {# cijfers}} bevatten",
+ "passwordSpecialCharacterRequired": "Het wachtwoord moet minimaal één speciaal teken bevatten",
+ "passwordsMustMatch": "De wachtwoorden komen niet overeen",
+ "confirmPasswordRequired": "Bevestig je wachtwoord"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "We hebben gezien dat je artikelen in een eerder winkelmandje had opgeslagen, dus we hebben ze voor je aan je huidige winkelmandje toegevoegd.",
"cartRestored": "Je bent een winkelmandje begonnen op een ander apparaat en we hebben het hier hersteld, zodat je verder kunt gaan waar je was gebleven.",
"cartUpdateInProgress": "Je winkelwagentje wordt bijgewerkt. Weet je zeker dat je deze pagina wilt verlaten? Je wijzigingen kunnen verloren gaan.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "De oorspronkelijke prijs was {price}.",
+ "currentPrice": "De huidige prijs is {price}.",
+ "quantityReadyToShip": "{quantity, number} klaar voor verzending",
+ "quantityOnBackorder": "{quantity, number} staat in backorder",
+ "partiallyAvailable": "Slechts {quantity, number} beschikbaar",
"CheckoutSummary": {
"title": "Overzicht",
"subTotal": "Subtotaal",
@@ -335,7 +402,8 @@
"updateShipping": "Verzending bijwerken",
"addShipping": "Verzending toevoegen",
"cartNotFound": "Er is een fout opgetreden bij het ophalen van je winkelwagen",
- "noShippingOptions": "Er zijn geen verzendopties beschikbaar voor je adres"
+ "noShippingOptions": "Er zijn geen verzendopties beschikbaar voor je adres",
+ "countryRequired": "Land is vereist"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Aanvullende informatie",
"currentStock": "{quantity, number} op voorraad",
"backorderQuantity": "{hoeveelheid, aantal} staat in backorder",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Toevoegen aan winkelmandje",
"outOfStock": "Niet op voorraad",
@@ -427,13 +497,24 @@
"button": "Schrijf een beoordeling",
"title": "Schrijf een beoordeling",
"submit": "Verzenden",
+ "cancel": "Annuleren",
"ratingLabel": "Beoordeling",
"titleLabel": "Titel",
"reviewLabel": "Beoordelen",
"nameLabel": "Naam",
"emailLabel": "E-mailadres",
"successMessage": "Je beoordeling is succesvol ingediend!",
- "somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw."
+ "somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw.",
+ "FieldErrors": {
+ "titleRequired": "Titel is vereist",
+ "authorRequired": "Naam is verplicht",
+ "emailRequired": "E-mailadres is vereist",
+ "emailInvalid": "Voer een geldig e-mailadres in",
+ "textRequired": "Beoordeling is vereist",
+ "ratingRequired": "Beoordeling is vereist",
+ "ratingTooSmall": "De beoordeling moet minimaal 1 zijn",
+ "ratingTooLarge": "De beoordeling moet maximaal 5 zijn"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Blijf op de hoogte van het laatste nieuws en aanbiedingen van onze winkel.",
"subscribedToNewsletter": "Je bent nu geabonneerd op onze nieuwsbrief!",
"Errors": {
- "invalidEmail": "Voer een geldig e-mailadres in.",
+ "emailRequired": "E-mailadres is vereist",
+ "invalidEmail": "Voer een geldig e-mailadres in",
"somethingWentWrong": "Er is iets fout gegaan. Probeer het later opnieuw."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "De oorspronkelijke prijs was {price}.",
+ "currentPrice": "De huidige prijs is {price}.",
+ "range": "Prijs van {minValue} tot {maxValue}."
}
},
"GiftCertificates": {
@@ -574,7 +656,7 @@
"title": "Saldo controleren",
"description": "Je kunt het saldo controleren en de informatie over je cadeaubon opvragen door de code in het vak hieronder in te voeren.",
"inputLabel": "Code",
- "inputPlaceholder": "xxx-xxx-xxx-xxx",
+ "inputPlaceholder": "XXX-XXX-XXX-XXX",
"purchasedDateLabel": "Gekocht",
"senderLabel": "Van",
"Errors": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Ik erken dat deze cadeaubon vervalt op {expiryDate}",
"ctaLabel": "Toevoegen aan winkelmandje",
"Errors": {
- "amountRequired": "Selecteer of voer een cadeaubonbedrag in.",
- "amountInvalid": "Selecteer een geldig cadeaubonbedrag.",
- "amountOutOfRange": "Voer een bedrag in tussen {minAmount} en {maxAmount}.",
- "unexpectedSettingsError": "Er is een onverwachte fout opgetreden bij het ophalen van de instellingen voor de cadeaubon. Probeer het later opnieuw."
+ "amountRequired": "Selecteer of voer een cadeaubonbedrag in",
+ "amountInvalid": "Selecteer een geldig cadeaubonbedrag",
+ "amountOutOfRange": "Voer een bedrag in tussen {minAmount} en {maxAmount}",
+ "unexpectedSettingsError": "Er is een onverwachte fout opgetreden bij het ophalen van de instellingen voor de cadeaubon. Probeer het later opnieuw.",
+ "senderNameRequired": "Uw naam is verplicht",
+ "senderEmailRequired": "Uw e-mailadres is vereist",
+ "recipientNameRequired": "De naam van de ontvanger is vereist",
+ "recipientEmailRequired": "Het e-mailadres van de ontvanger is vereist",
+ "emailInvalid": "Voer een geldig e-mailadres in",
+ "checkboxRequired": "U moet dit vakje aanvinken om door te gaan"
}
}
}
},
"Form": {
- "optional": "optioneel"
+ "optional": "optioneel",
+ "Errors": {
+ "invalidInput": "Controleer uw invoer en probeer het opnieuw",
+ "invalidFormat": "De ingevoerde waarde komt niet overeen met het vereiste formaat"
+ }
}
}
diff --git a/core/messages/no.json b/core/messages/no.json
index 7cc6eecc7..99b29e946 100644
--- a/core/messages/no.json
+++ b/core/messages/no.json
@@ -43,7 +43,17 @@
"newPassword": "Nytt passord",
"confirmPassword": "Bekreft passord",
"passwordUpdated": "Passordet er oppdatert!",
- "somethingWentWrong": "Noe gikk galt. Prøv igjen senere."
+ "somethingWentWrong": "Noe gikk galt. Prøv igjen senere.",
+ "FieldErrors": {
+ "passwordRequired": "Passord er påkrevd",
+ "passwordTooSmall": "Passordet må være minst {minLength, plural, =1 {1 character} other {# tegn}} langt",
+ "passwordLowercaseRequired": "Passordet må inneholde minst én liten bokstav",
+ "passwordUppercaseRequired": "Passordet må inneholde minst én stor bokstav",
+ "passwordNumberRequired": "Passordet må inneholde minst {minNumbers, plural, =1 {ett tall} other {# tall}}",
+ "passwordSpecialCharacterRequired": "Passordet må inneholde minst ett spesialtegn",
+ "passwordsMustMatch": "Passordene stemmer ikke overens",
+ "confirmPasswordRequired": "Bekreft passordet ditt"
+ }
},
"Login": {
"title": "Logg inn",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Noe gikk galt. Prøv igjen senere.",
"passwordResetRequired": "Krever tilbakestilling av passord. Kontroller e-posten din for instruksjoner om hvordan du tilbakestiller passordet.",
"invalidToken": "Innloggingskoblingen din er ugyldig eller har utløpt. Prøv å logge inn igjen.",
+ "FieldErrors": {
+ "emailRequired": "E-post er påkrevd",
+ "emailInvalid": "Skriv inn en gyldig e-postadresse",
+ "passwordRequired": "Passord er påkrevd",
+ "invalidInput": "Sjekk inndataene dine og prøv igjen."
+ },
"CreateAccount": {
"title": "Ny kunde?",
"accountBenefits": "Opprett en konto hos oss, så kan du:",
@@ -70,14 +86,36 @@
"title": "Glemt passord",
"subtitle": "Skriv inn e-posten som er knyttet til kontoen din nedenfor. Vi sender deg instruksjoner for å tilbakestille passordet ditt.",
"confirmResetPassword": "Hvis e-postadressen {email} er koblet til en konto i butikken vår, har vi sendt deg en e-post for tilbakestilling av passord. Sjekk innboksen og søppelpostmappen hvis du ikke ser den.",
- "somethingWentWrong": "Noe gikk galt. Prøv igjen senere."
+ "somethingWentWrong": "Noe gikk galt. Prøv igjen senere.",
+ "FieldErrors": {
+ "emailRequired": "E-post er påkrevd",
+ "emailInvalid": "Skriv inn en gyldig e-postadresse"
+ }
}
},
"Register": {
"title": "Registrer deg for en konto",
"heading": "Ny konto",
"cta": "Opprett konto",
- "somethingWentWrong": "Noe gikk galt. Prøv igjen senere."
+ "somethingWentWrong": "Noe gikk galt. Prøv igjen senere.",
+ "FieldErrors": {
+ "firstNameRequired": "Fornavn er påkrevd",
+ "lastNameRequired": "Etternavn er påkrevd",
+ "emailRequired": "E-post er påkrevd",
+ "emailInvalid": "Skriv inn en gyldig e-postadresse",
+ "passwordRequired": "Passord er påkrevd",
+ "passwordTooSmall": "Passordet må være minst {minLength, plural, =1 {1 character} other {# tegn}} langt",
+ "passwordLowercaseRequired": "Passordet må inneholde minst én liten bokstav",
+ "passwordUppercaseRequired": "Passordet må inneholde minst én stor bokstav",
+ "passwordNumberRequired": "Passordet må inneholde minst {minNumbers, plural, =1 {ett tall} other {# tall}}",
+ "passwordSpecialCharacterRequired": "Passordet må inneholde minst ett spesialtegn",
+ "passwordsMustMatch": "Passordene stemmer ikke overens",
+ "addressLine1Required": "Adresselinje 1 er påkrevd",
+ "cityRequired": "By er påkrevd",
+ "countryRequired": "Land er påkrevd",
+ "stateRequired": "Delstat/provins er påkrevd",
+ "postalCodeRequired": "Postnummer er påkrevd"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Noe gikk galt. Prøv igjen senere.",
"EmptyState": {
"title": "Du har ingen adresser"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Fornavn er påkrevd",
+ "lastNameRequired": "Etternavn er påkrevd",
+ "addressLine1Required": "Adresselinje 1 er påkrevd",
+ "cityRequired": "By er påkrevd",
+ "countryRequired": "Land er påkrevd",
+ "stateRequired": "Delstat/provins er påkrevd",
+ "postalCodeRequired": "Postnummer er påkrevd"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Abonner på nyhetsbrevet vårt.",
"marketingPreferencesUpdated": "Markedsføringsinnstillingene er oppdatert!",
"somethingWentWrong": "Noe gikk galt. Prøv igjen senere."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Fornavn er påkrevd",
+ "firstNameTooSmall": "Fornavnet må være minst 2 tegn langt",
+ "lastNameRequired": "Etternavn er påkrevd",
+ "lastNameTooSmall": "Etternavnet må være minst 2 tegn langt",
+ "emailRequired": "E-post er påkrevd",
+ "emailInvalid": "Skriv inn en gyldig e-postadresse",
+ "currentPasswordRequired": "Gjeldende passord kreves",
+ "passwordRequired": "Passord er påkrevd",
+ "passwordTooSmall": "Passordet må være minst {minLength, plural, =1 {1 character} other {# tegn}} langt",
+ "passwordLowercaseRequired": "Passordet må inneholde minst én liten bokstav",
+ "passwordUppercaseRequired": "Passordet må inneholde minst én stor bokstav",
+ "passwordNumberRequired": "Passordet må inneholde minst {minNumbers, plural, =1 {ett tall} other {# tall}}",
+ "passwordSpecialCharacterRequired": "Passordet må inneholde minst ett spesialtegn",
+ "passwordsMustMatch": "Passordene stemmer ikke overens",
+ "confirmPasswordRequired": "Bekreft passordet ditt"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Vi la merke til at du hadde varer lagret i en tidligere handlekurv, så vi har lagt dem til i din nåværende handlekurv for deg.",
"cartRestored": "Du startet en handlekurv på en annen enhet, og vi har gjenopprettet den her, slik at du kan fortsette der du slapp.",
"cartUpdateInProgress": "Du har en handlekurvoppdatering i gang. Er du sikker på at du vil forlate denne siden? Endringene kan gå tapt.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "Opprinnelig pris var {price}.",
+ "currentPrice": "Nåværende pris er {price}.",
+ "quantityReadyToShip": "{antall, number} klar til sending",
+ "quantityOnBackorder": "{antall, nummer} vil være restordre",
+ "partiallyAvailable": "Kun {antall, number} tilgjengelig",
"CheckoutSummary": {
"title": "Sammendrag",
"subTotal": "Delsum",
@@ -335,7 +402,8 @@
"updateShipping": "Oppdater forsendelse",
"addShipping": "Legg til forsendelse",
"cartNotFound": "Det oppsto en feil da du hentet handlekurven din",
- "noShippingOptions": "Det finnes ingen tilgjengelige forsendelsesalternativer for adressen din"
+ "noShippingOptions": "Det finnes ingen tilgjengelige forsendelsesalternativer for adressen din",
+ "countryRequired": "Land er påkrevd"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Mer informasjon",
"currentStock": "{antall, nummer} på lager",
"backorderQuantity": "{antall, nummer} vil være restordre",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Legg i handlekurv",
"outOfStock": "Utsolgt",
@@ -427,13 +497,24 @@
"button": "Skriv en anmeldelse",
"title": "Skriv en anmeldelse",
"submit": "Send inn",
+ "cancel": "Avbryt",
"ratingLabel": "Vurdering",
"titleLabel": "Tittel",
"reviewLabel": "Anmeldelse",
"nameLabel": "Navn",
"emailLabel": "E-post",
"successMessage": "Din anmeldelse er sendt inn!",
- "somethingWentWrong": "Noe gikk galt. Prøv igjen senere."
+ "somethingWentWrong": "Noe gikk galt. Prøv igjen senere.",
+ "FieldErrors": {
+ "titleRequired": "Tittel er påkrevd",
+ "authorRequired": "Navn er påkrevd",
+ "emailRequired": "E-post er påkrevd",
+ "emailInvalid": "Skriv inn en gyldig e-postadresse",
+ "textRequired": "Gjennomgang er nødvendig",
+ "ratingRequired": "Vurdering er påkrevd",
+ "ratingTooSmall": "Vurderingen må være minst 1",
+ "ratingTooLarge": "Vurderingen må være maksimalt 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Hold deg oppdatert med de siste nyhetene og tilbudene fra butikken vår.",
"subscribedToNewsletter": "Du har abonnert på nyhetsbrevet vårt.",
"Errors": {
- "invalidEmail": "Skriv inn en gyldig e-postadresse.",
+ "emailRequired": "E-post er påkrevd",
+ "invalidEmail": "Skriv inn en gyldig e-postadresse",
"somethingWentWrong": "Noe gikk galt. Prøv igjen senere."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "Opprinnelig pris var {price}.",
+ "currentPrice": "Nåværende pris er {price}.",
+ "range": "Pris fra {minValue} til {maxValue}."
}
},
"GiftCertificates": {
@@ -574,7 +656,7 @@
"title": "Sjekk saldo",
"description": "Du kan sjekke saldoen og få informasjon om gavekortet ved å skrive inn koden i boksen nedenfor.",
"inputLabel": "Kode",
- "inputPlaceholder": "xxx-xxx-xxx-xxx",
+ "inputPlaceholder": "XXX-XXX-XXX-XXX",
"purchasedDateLabel": "Kjøpt",
"senderLabel": "Fra",
"Errors": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Jeg erkjenner at dette gavekortet utløper {expiryDate}",
"ctaLabel": "Legg i handlekurv",
"Errors": {
- "amountRequired": "Velg eller skriv inn et beløp for gavekortet.",
- "amountInvalid": "Velg et gyldig gavekortbeløp.",
- "amountOutOfRange": "Skriv inn et beløp mellom {minAmount} og {maxAmount}.",
- "unexpectedSettingsError": "Det oppstod en uventet feil under henting av innstillinger for gavekort. Prøv på nytt senere."
+ "amountRequired": "Velg eller skriv inn et gavekortbeløp",
+ "amountInvalid": "Velg et gyldig gavekortbeløp",
+ "amountOutOfRange": "Skriv inn et beløp mellom {minAmount} og {maxAmount}",
+ "unexpectedSettingsError": "Det oppstod en uventet feil under henting av innstillinger for gavekort. Prøv på nytt senere.",
+ "senderNameRequired": "Ditt navn er påkrevd",
+ "senderEmailRequired": "Din e-postadresse er påkrevd",
+ "recipientNameRequired": "Mottakerens navn er obligatorisk",
+ "recipientEmailRequired": "Mottakerens e-postadresse er obligatorisk",
+ "emailInvalid": "Skriv inn en gyldig e-postadresse",
+ "checkboxRequired": "Du må krysse av i denne boksen for å fortsette"
}
}
}
},
"Form": {
- "optional": "valgfri"
+ "optional": "valgfri",
+ "Errors": {
+ "invalidInput": "Sjekk inndataene dine og prøv igjen",
+ "invalidFormat": "Den angitte verdien samsvarer ikke med det nødvendige formatet"
+ }
}
}
diff --git a/core/messages/pl.json b/core/messages/pl.json
index 61dbadc8a..07320b139 100644
--- a/core/messages/pl.json
+++ b/core/messages/pl.json
@@ -43,7 +43,17 @@
"newPassword": "Nowe hasło",
"confirmPassword": "Potwierdź hasło",
"passwordUpdated": "Hasło zostało pomyślnie zaktualizowane!",
- "somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później."
+ "somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później.",
+ "FieldErrors": {
+ "passwordRequired": "Hasło jest wymagane",
+ "passwordTooSmall": "Password must be at least {minLength, plural, =1 {1 character} other {# characters}} long",
+ "passwordLowercaseRequired": "Password must contain at least one lowercase letter",
+ "passwordUppercaseRequired": "Password must contain at least one uppercase letter",
+ "passwordNumberRequired": "Password must contain at least {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Password must contain at least one special character",
+ "passwordsMustMatch": "The passwords do not match",
+ "confirmPasswordRequired": "Please confirm your password"
+ }
},
"Login": {
"title": "Zaloguj się",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później.",
"passwordResetRequired": "Password reset required. Please check your email for instructions to reset your password.",
"invalidToken": "Your login link is invalid or has expired. Please try logging in again.",
+ "FieldErrors": {
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "passwordRequired": "Hasło jest wymagane",
+ "invalidInput": "Please check your input and try again."
+ },
"CreateAccount": {
"title": "Nowy klient?",
"accountBenefits": "Załóż u nas konto, a będziesz mógł:",
@@ -70,14 +86,36 @@
"title": "Nie pamiętam hasła",
"subtitle": "Podaj poniżej adres e-mail powiązany z Twoim kontem. Wyślemy Ci instrukcje resetowania hasła.",
"confirmResetPassword": "Jeśli adres e-mail {email} jest powiązany z kontem w naszym sklepie, otrzymasz wiadomość e-mail umożliwiającą zresetowanie hasła. Jeśli jej nie widzisz, sprawdź skrzynkę odbiorczą i folder ze spamem.",
- "somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później."
+ "somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później.",
+ "FieldErrors": {
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address"
+ }
}
},
"Register": {
"title": "Zarejestruj konto",
"heading": "Nowe konto",
"cta": "Utwórz konto",
- "somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później."
+ "somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później.",
+ "FieldErrors": {
+ "firstNameRequired": "Imię jest wymagane",
+ "lastNameRequired": "Nazwisko jest wymagane",
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "passwordRequired": "Hasło jest wymagane",
+ "passwordTooSmall": "Password must be at least {minLength, plural, =1 {1 character} other {# characters}} long",
+ "passwordLowercaseRequired": "Password must contain at least one lowercase letter",
+ "passwordUppercaseRequired": "Password must contain at least one uppercase letter",
+ "passwordNumberRequired": "Password must contain at least {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Password must contain at least one special character",
+ "passwordsMustMatch": "The passwords do not match",
+ "addressLine1Required": "Address line 1 is required",
+ "cityRequired": "Miasto jest wymagane",
+ "countryRequired": "Wymagany jest kraj",
+ "stateRequired": "Wymagany jest stan/prowincja",
+ "postalCodeRequired": "Kod pocztowy jest wymagany"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później.",
"EmptyState": {
"title": "You don't have any addresses"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Imię jest wymagane",
+ "lastNameRequired": "Nazwisko jest wymagane",
+ "addressLine1Required": "Address line 1 is required",
+ "cityRequired": "Miasto jest wymagane",
+ "countryRequired": "Wymagany jest kraj",
+ "stateRequired": "Wymagany jest stan/prowincja",
+ "postalCodeRequired": "Kod pocztowy jest wymagany"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Zapisz się do naszego newslettera.",
"marketingPreferencesUpdated": "Marketing preferences have been updated successfully!",
"somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Imię jest wymagane",
+ "firstNameTooSmall": "First name must be at least 2 characters long",
+ "lastNameRequired": "Nazwisko jest wymagane",
+ "lastNameTooSmall": "Last name must be at least 2 characters long",
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "currentPasswordRequired": "Wymagane jest aktualne hasło",
+ "passwordRequired": "Hasło jest wymagane",
+ "passwordTooSmall": "Password must be at least {minLength, plural, =1 {1 character} other {# characters}} long",
+ "passwordLowercaseRequired": "Password must contain at least one lowercase letter",
+ "passwordUppercaseRequired": "Password must contain at least one uppercase letter",
+ "passwordNumberRequired": "Password must contain at least {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Password must contain at least one special character",
+ "passwordsMustMatch": "The passwords do not match",
+ "confirmPasswordRequired": "Please confirm your password"
}
}
},
@@ -306,6 +370,9 @@
"cartUpdateInProgress": "You have a cart update in progress. Are you sure you want to leave this page? Your changes may be lost.",
"originalPrice": "Original price was {price}.",
"currentPrice": "Current price is {price}.",
+ "quantityReadyToShip": "{quantity, number} ready to ship",
+ "quantityOnBackorder": "{quantity, number} will be backordered",
+ "partiallyAvailable": "Only {quantity, number} available",
"CheckoutSummary": {
"title": "Podsumowanie",
"subTotal": "Suma cząstkowa",
@@ -335,7 +402,8 @@
"updateShipping": "Zaktualizuj wysyłkę",
"addShipping": "Dodaj wysyłkę",
"cartNotFound": "An error occurred when retrieving your cart",
- "noShippingOptions": "Brak dostępnych opcji wysyłki dla Państwa adresu"
+ "noShippingOptions": "Brak dostępnych opcji wysyłki dla Państwa adresu",
+ "countryRequired": "Wymagany jest kraj"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Informacje dodatkowe",
"currentStock": "{quantity, number} in stock",
"backorderQuantity": "{quantity, number} will be on backorder",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Dodaj do koszyka",
"outOfStock": "Brak w magazynie",
@@ -427,13 +497,24 @@
"button": "Write a review",
"title": "Write a review",
"submit": "Wyślij",
+ "cancel": "Anuluj",
"ratingLabel": "Ocena",
"titleLabel": "Tytuł",
"reviewLabel": "Przegląd",
"nameLabel": "Nazwa",
"emailLabel": "Email",
"successMessage": "Your review has been submitted successfully!",
- "somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później."
+ "somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później.",
+ "FieldErrors": {
+ "titleRequired": "Title is required",
+ "authorRequired": "Nazwa jest wymagana",
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "textRequired": "Review is required",
+ "ratingRequired": "Rating is required",
+ "ratingTooSmall": "Rating must be at least 1",
+ "ratingTooLarge": "Rating must be at most 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Bądź na bieżąco z najnowszymi informacjami i ofertami naszego sklepu.",
"subscribedToNewsletter": "You have been subscribed to our newsletter!",
"Errors": {
- "invalidEmail": "Wpisz prawidłowy adres e-mail.",
+ "emailRequired": "Email is required",
+ "invalidEmail": "Please enter a valid email address",
"somethingWentWrong": "Coś poszło nie tak. Proszę spróbować później."
}
},
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "I acknowledge that this Gift Certificate will expire on {expiryDate}",
"ctaLabel": "Dodaj do koszyka",
"Errors": {
- "amountRequired": "Please select or enter a gift certificate amount.",
- "amountInvalid": "Please select a valid gift certificate amount.",
- "amountOutOfRange": "Please enter an amount between {minAmount} and {maxAmount}.",
- "unexpectedSettingsError": "An unexpected error occurred while retrieving gift certificate settings. Please try again later."
+ "amountRequired": "Please select or enter a gift certificate amount",
+ "amountInvalid": "Please select a valid gift certificate amount",
+ "amountOutOfRange": "Please enter an amount between {minAmount} and {maxAmount}",
+ "unexpectedSettingsError": "An unexpected error occurred while retrieving gift certificate settings. Please try again later.",
+ "senderNameRequired": "Your name is required",
+ "senderEmailRequired": "Your email is required",
+ "recipientNameRequired": "Recipient's name is required",
+ "recipientEmailRequired": "Recipient's email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "checkboxRequired": "You must check this box to continue"
}
}
}
},
"Form": {
- "optional": "opcjonalne"
+ "optional": "opcjonalne",
+ "Errors": {
+ "invalidInput": "Please check your input and try again",
+ "invalidFormat": "The value entered does not match the required format"
+ }
}
}
diff --git a/core/messages/pt-BR.json b/core/messages/pt-BR.json
index dd7f7f5b9..5675ebd3e 100644
--- a/core/messages/pt-BR.json
+++ b/core/messages/pt-BR.json
@@ -43,7 +43,17 @@
"newPassword": "Nova senha",
"confirmPassword": "Confirmar senha",
"passwordUpdated": "A senha foi atualizada com sucesso!",
- "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
+ "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
+ "FieldErrors": {
+ "passwordRequired": "A senha é obrigatória",
+ "passwordTooSmall": "Password must be at least {minLength, plural, =1 {1 character} other {# characters}} long",
+ "passwordLowercaseRequired": "Password must contain at least one lowercase letter",
+ "passwordUppercaseRequired": "Password must contain at least one uppercase letter",
+ "passwordNumberRequired": "Password must contain at least {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Password must contain at least one special character",
+ "passwordsMustMatch": "The passwords do not match",
+ "confirmPasswordRequired": "Please confirm your password"
+ }
},
"Login": {
"title": "Acesso",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
"passwordResetRequired": "Password reset required. Please check your email for instructions to reset your password.",
"invalidToken": "Your login link is invalid or has expired. Please try logging in again.",
+ "FieldErrors": {
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "passwordRequired": "A senha é obrigatória",
+ "invalidInput": "Please check your input and try again."
+ },
"CreateAccount": {
"title": "Cliente novo?",
"accountBenefits": "Crie uma conta conosco para poder:",
@@ -70,14 +86,36 @@
"title": "Esqueci a senha",
"subtitle": "Insira abaixo o e-mail associado à sua conta. Enviaremos instruções para redefinir sua senha.",
"confirmResetPassword": "Se o endereço de e-mail {email} está vinculado a uma conta na nossa loja, enviamos um e-mail de redefinição de senha. Verifique sua caixa de entrada e, caso não encontre, confira a pasta de spam.",
- "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
+ "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
+ "FieldErrors": {
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address"
+ }
}
},
"Register": {
"title": "Registrar conta",
"heading": "Nova conta",
"cta": "Criar conta",
- "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
+ "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
+ "FieldErrors": {
+ "firstNameRequired": "O primeiro nome é obrigatório",
+ "lastNameRequired": "O sobrenome é obrigatório",
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "passwordRequired": "A senha é obrigatória",
+ "passwordTooSmall": "Password must be at least {minLength, plural, =1 {1 character} other {# characters}} long",
+ "passwordLowercaseRequired": "Password must contain at least one lowercase letter",
+ "passwordUppercaseRequired": "Password must contain at least one uppercase letter",
+ "passwordNumberRequired": "Password must contain at least {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Password must contain at least one special character",
+ "passwordsMustMatch": "The passwords do not match",
+ "addressLine1Required": "Address line 1 is required",
+ "cityRequired": "É obrigatório informar a cidade",
+ "countryRequired": "O país é obrigatório",
+ "stateRequired": "Estado/Província é obrigatório",
+ "postalCodeRequired": "O código postal é obrigatório"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
"EmptyState": {
"title": "You don't have any addresses"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "O primeiro nome é obrigatório",
+ "lastNameRequired": "O sobrenome é obrigatório",
+ "addressLine1Required": "Address line 1 is required",
+ "cityRequired": "É obrigatório informar a cidade",
+ "countryRequired": "O país é obrigatório",
+ "stateRequired": "Estado/Província é obrigatório",
+ "postalCodeRequired": "O código postal é obrigatório"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Inscreva-se no nosso boletim informativo.",
"marketingPreferencesUpdated": "Marketing preferences have been updated successfully!",
"somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "O primeiro nome é obrigatório",
+ "firstNameTooSmall": "First name must be at least 2 characters long",
+ "lastNameRequired": "O sobrenome é obrigatório",
+ "lastNameTooSmall": "Last name must be at least 2 characters long",
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "currentPasswordRequired": "A senha atual é obrigatória",
+ "passwordRequired": "A senha é obrigatória",
+ "passwordTooSmall": "Password must be at least {minLength, plural, =1 {1 character} other {# characters}} long",
+ "passwordLowercaseRequired": "Password must contain at least one lowercase letter",
+ "passwordUppercaseRequired": "Password must contain at least one uppercase letter",
+ "passwordNumberRequired": "Password must contain at least {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Password must contain at least one special character",
+ "passwordsMustMatch": "The passwords do not match",
+ "confirmPasswordRequired": "Please confirm your password"
}
}
},
@@ -306,6 +370,9 @@
"cartUpdateInProgress": "You have a cart update in progress. Are you sure you want to leave this page? Your changes may be lost.",
"originalPrice": "Original price was {price}.",
"currentPrice": "Current price is {price}.",
+ "quantityReadyToShip": "{quantity, number} ready to ship",
+ "quantityOnBackorder": "{quantity, number} will be backordered",
+ "partiallyAvailable": "Only {quantity, number} available",
"CheckoutSummary": {
"title": "Resumo",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Atualizar envio",
"addShipping": "Adicionar envio",
"cartNotFound": "An error occurred when retrieving your cart",
- "noShippingOptions": "Não há opções de envio disponíveis para o seu endereço"
+ "noShippingOptions": "Não há opções de envio disponíveis para o seu endereço",
+ "countryRequired": "O país é obrigatório"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Outras informações",
"currentStock": "{quantity, number} in stock",
"backorderQuantity": "{quantity, number} will be on backorder",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Adicionar ao carrinho",
"outOfStock": "Fora do estoque",
@@ -427,13 +497,24 @@
"button": "Write a review",
"title": "Write a review",
"submit": "Enviar",
+ "cancel": "Cancelar",
"ratingLabel": "Taxa",
"titleLabel": "Título",
"reviewLabel": "Avaliação",
"nameLabel": "Nome",
"emailLabel": "Email",
"successMessage": "Your review has been submitted successfully!",
- "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
+ "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
+ "FieldErrors": {
+ "titleRequired": "Title is required",
+ "authorRequired": "O nome é obrigatório",
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "textRequired": "Review is required",
+ "ratingRequired": "Rating is required",
+ "ratingTooSmall": "Rating must be at least 1",
+ "ratingTooLarge": "Rating must be at most 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Fique por dentro das últimas novidades e ofertas da nossa loja.",
"subscribedToNewsletter": "You have been subscribed to our newsletter!",
"Errors": {
- "invalidEmail": "Informe um endereço de email válido.",
+ "emailRequired": "Email is required",
+ "invalidEmail": "Please enter a valid email address",
"somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
}
},
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "I acknowledge that this Gift Certificate will expire on {expiryDate}",
"ctaLabel": "Adicionar ao carrinho",
"Errors": {
- "amountRequired": "Please select or enter a gift certificate amount.",
- "amountInvalid": "Please select a valid gift certificate amount.",
- "amountOutOfRange": "Please enter an amount between {minAmount} and {maxAmount}.",
- "unexpectedSettingsError": "An unexpected error occurred while retrieving gift certificate settings. Please try again later."
+ "amountRequired": "Please select or enter a gift certificate amount",
+ "amountInvalid": "Please select a valid gift certificate amount",
+ "amountOutOfRange": "Please enter an amount between {minAmount} and {maxAmount}",
+ "unexpectedSettingsError": "An unexpected error occurred while retrieving gift certificate settings. Please try again later.",
+ "senderNameRequired": "Your name is required",
+ "senderEmailRequired": "Your email is required",
+ "recipientNameRequired": "Recipient's name is required",
+ "recipientEmailRequired": "Recipient's email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "checkboxRequired": "You must check this box to continue"
}
}
}
},
"Form": {
- "optional": "Opcional"
+ "optional": "Opcional",
+ "Errors": {
+ "invalidInput": "Please check your input and try again",
+ "invalidFormat": "The value entered does not match the required format"
+ }
}
}
diff --git a/core/messages/pt.json b/core/messages/pt.json
index dd7f7f5b9..5675ebd3e 100644
--- a/core/messages/pt.json
+++ b/core/messages/pt.json
@@ -43,7 +43,17 @@
"newPassword": "Nova senha",
"confirmPassword": "Confirmar senha",
"passwordUpdated": "A senha foi atualizada com sucesso!",
- "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
+ "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
+ "FieldErrors": {
+ "passwordRequired": "A senha é obrigatória",
+ "passwordTooSmall": "Password must be at least {minLength, plural, =1 {1 character} other {# characters}} long",
+ "passwordLowercaseRequired": "Password must contain at least one lowercase letter",
+ "passwordUppercaseRequired": "Password must contain at least one uppercase letter",
+ "passwordNumberRequired": "Password must contain at least {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Password must contain at least one special character",
+ "passwordsMustMatch": "The passwords do not match",
+ "confirmPasswordRequired": "Please confirm your password"
+ }
},
"Login": {
"title": "Acesso",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
"passwordResetRequired": "Password reset required. Please check your email for instructions to reset your password.",
"invalidToken": "Your login link is invalid or has expired. Please try logging in again.",
+ "FieldErrors": {
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "passwordRequired": "A senha é obrigatória",
+ "invalidInput": "Please check your input and try again."
+ },
"CreateAccount": {
"title": "Cliente novo?",
"accountBenefits": "Crie uma conta conosco para poder:",
@@ -70,14 +86,36 @@
"title": "Esqueci a senha",
"subtitle": "Insira abaixo o e-mail associado à sua conta. Enviaremos instruções para redefinir sua senha.",
"confirmResetPassword": "Se o endereço de e-mail {email} está vinculado a uma conta na nossa loja, enviamos um e-mail de redefinição de senha. Verifique sua caixa de entrada e, caso não encontre, confira a pasta de spam.",
- "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
+ "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
+ "FieldErrors": {
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address"
+ }
}
},
"Register": {
"title": "Registrar conta",
"heading": "Nova conta",
"cta": "Criar conta",
- "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
+ "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
+ "FieldErrors": {
+ "firstNameRequired": "O primeiro nome é obrigatório",
+ "lastNameRequired": "O sobrenome é obrigatório",
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "passwordRequired": "A senha é obrigatória",
+ "passwordTooSmall": "Password must be at least {minLength, plural, =1 {1 character} other {# characters}} long",
+ "passwordLowercaseRequired": "Password must contain at least one lowercase letter",
+ "passwordUppercaseRequired": "Password must contain at least one uppercase letter",
+ "passwordNumberRequired": "Password must contain at least {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Password must contain at least one special character",
+ "passwordsMustMatch": "The passwords do not match",
+ "addressLine1Required": "Address line 1 is required",
+ "cityRequired": "É obrigatório informar a cidade",
+ "countryRequired": "O país é obrigatório",
+ "stateRequired": "Estado/Província é obrigatório",
+ "postalCodeRequired": "O código postal é obrigatório"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
"EmptyState": {
"title": "You don't have any addresses"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "O primeiro nome é obrigatório",
+ "lastNameRequired": "O sobrenome é obrigatório",
+ "addressLine1Required": "Address line 1 is required",
+ "cityRequired": "É obrigatório informar a cidade",
+ "countryRequired": "O país é obrigatório",
+ "stateRequired": "Estado/Província é obrigatório",
+ "postalCodeRequired": "O código postal é obrigatório"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Inscreva-se no nosso boletim informativo.",
"marketingPreferencesUpdated": "Marketing preferences have been updated successfully!",
"somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "O primeiro nome é obrigatório",
+ "firstNameTooSmall": "First name must be at least 2 characters long",
+ "lastNameRequired": "O sobrenome é obrigatório",
+ "lastNameTooSmall": "Last name must be at least 2 characters long",
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "currentPasswordRequired": "A senha atual é obrigatória",
+ "passwordRequired": "A senha é obrigatória",
+ "passwordTooSmall": "Password must be at least {minLength, plural, =1 {1 character} other {# characters}} long",
+ "passwordLowercaseRequired": "Password must contain at least one lowercase letter",
+ "passwordUppercaseRequired": "Password must contain at least one uppercase letter",
+ "passwordNumberRequired": "Password must contain at least {minNumbers, plural, =1 {one number} other {# numbers}}",
+ "passwordSpecialCharacterRequired": "Password must contain at least one special character",
+ "passwordsMustMatch": "The passwords do not match",
+ "confirmPasswordRequired": "Please confirm your password"
}
}
},
@@ -306,6 +370,9 @@
"cartUpdateInProgress": "You have a cart update in progress. Are you sure you want to leave this page? Your changes may be lost.",
"originalPrice": "Original price was {price}.",
"currentPrice": "Current price is {price}.",
+ "quantityReadyToShip": "{quantity, number} ready to ship",
+ "quantityOnBackorder": "{quantity, number} will be backordered",
+ "partiallyAvailable": "Only {quantity, number} available",
"CheckoutSummary": {
"title": "Resumo",
"subTotal": "Subtotal",
@@ -335,7 +402,8 @@
"updateShipping": "Atualizar envio",
"addShipping": "Adicionar envio",
"cartNotFound": "An error occurred when retrieving your cart",
- "noShippingOptions": "Não há opções de envio disponíveis para o seu endereço"
+ "noShippingOptions": "Não há opções de envio disponíveis para o seu endereço",
+ "countryRequired": "O país é obrigatório"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Outras informações",
"currentStock": "{quantity, number} in stock",
"backorderQuantity": "{quantity, number} will be on backorder",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Adicionar ao carrinho",
"outOfStock": "Fora do estoque",
@@ -427,13 +497,24 @@
"button": "Write a review",
"title": "Write a review",
"submit": "Enviar",
+ "cancel": "Cancelar",
"ratingLabel": "Taxa",
"titleLabel": "Título",
"reviewLabel": "Avaliação",
"nameLabel": "Nome",
"emailLabel": "Email",
"successMessage": "Your review has been submitted successfully!",
- "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
+ "somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde.",
+ "FieldErrors": {
+ "titleRequired": "Title is required",
+ "authorRequired": "O nome é obrigatório",
+ "emailRequired": "Email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "textRequired": "Review is required",
+ "ratingRequired": "Rating is required",
+ "ratingTooSmall": "Rating must be at least 1",
+ "ratingTooLarge": "Rating must be at most 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Fique por dentro das últimas novidades e ofertas da nossa loja.",
"subscribedToNewsletter": "You have been subscribed to our newsletter!",
"Errors": {
- "invalidEmail": "Informe um endereço de email válido.",
+ "emailRequired": "Email is required",
+ "invalidEmail": "Please enter a valid email address",
"somethingWentWrong": "Ocorreu um erro. Tente novamente mais tarde."
}
},
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "I acknowledge that this Gift Certificate will expire on {expiryDate}",
"ctaLabel": "Adicionar ao carrinho",
"Errors": {
- "amountRequired": "Please select or enter a gift certificate amount.",
- "amountInvalid": "Please select a valid gift certificate amount.",
- "amountOutOfRange": "Please enter an amount between {minAmount} and {maxAmount}.",
- "unexpectedSettingsError": "An unexpected error occurred while retrieving gift certificate settings. Please try again later."
+ "amountRequired": "Please select or enter a gift certificate amount",
+ "amountInvalid": "Please select a valid gift certificate amount",
+ "amountOutOfRange": "Please enter an amount between {minAmount} and {maxAmount}",
+ "unexpectedSettingsError": "An unexpected error occurred while retrieving gift certificate settings. Please try again later.",
+ "senderNameRequired": "Your name is required",
+ "senderEmailRequired": "Your email is required",
+ "recipientNameRequired": "Recipient's name is required",
+ "recipientEmailRequired": "Recipient's email is required",
+ "emailInvalid": "Please enter a valid email address",
+ "checkboxRequired": "You must check this box to continue"
}
}
}
},
"Form": {
- "optional": "Opcional"
+ "optional": "Opcional",
+ "Errors": {
+ "invalidInput": "Please check your input and try again",
+ "invalidFormat": "The value entered does not match the required format"
+ }
}
}
diff --git a/core/messages/sv.json b/core/messages/sv.json
index 4c7e300bb..539cab066 100644
--- a/core/messages/sv.json
+++ b/core/messages/sv.json
@@ -43,7 +43,17 @@
"newPassword": "Nytt lösenord",
"confirmPassword": "Bekräfta lösenord",
"passwordUpdated": "Lösenordet har uppdaterats!",
- "somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare."
+ "somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare.",
+ "FieldErrors": {
+ "passwordRequired": "Lösenord krävs",
+ "passwordTooSmall": "Lösenordet måste vara minst {minLength, plural, =1 {1 tecken} other {# tecken}} långt",
+ "passwordLowercaseRequired": "Lösenordet måste innehålla minst en liten bokstav",
+ "passwordUppercaseRequired": "Lösenordet måste innehålla minst en stor bokstav",
+ "passwordNumberRequired": "Lösenordet måste innehålla minst {minNumbers, plural, =1 {ett nummer} other {# nummer}}",
+ "passwordSpecialCharacterRequired": "Lösenordet måste innehålla minst ett specialtecken",
+ "passwordsMustMatch": "Lösenorden stämmer inte överens",
+ "confirmPasswordRequired": "Bekräfta ditt lösenord"
+ }
},
"Login": {
"title": "Logga in",
@@ -56,6 +66,12 @@
"somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare.",
"passwordResetRequired": "Återställning av lösenord krävs. Kontrollera din e-post för instruktioner om hur du återställer ditt lösenord.",
"invalidToken": "Din inloggningslänk är ogiltig eller har löpt ut. Försök logga in igen.",
+ "FieldErrors": {
+ "emailRequired": "E-postadress krävs",
+ "emailInvalid": "Ange en giltig e-postadress",
+ "passwordRequired": "Lösenord krävs",
+ "invalidInput": "Kontrollera din inmatning och försök igen."
+ },
"CreateAccount": {
"title": "Nya kunder?",
"accountBenefits": "Skapa ett konto hos oss, så kan du:",
@@ -70,14 +86,36 @@
"title": "Glömt ditt lösenord",
"subtitle": "Ange e-postadressen som är kopplad till ditt konto nedan. Vi skickar instruktioner för att återställa ditt lösenord.",
"confirmResetPassword": "Om e-postadressen {email} är kopplad till ett konto i vår butik har vi skickat ett e-postmeddelande om återställning av lösenord. Kontrollera din inkorg och skräppostmapp om du inte ser meddelandet.",
- "somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare."
+ "somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare.",
+ "FieldErrors": {
+ "emailRequired": "E-postadress krävs",
+ "emailInvalid": "Ange en giltig e-postadress"
+ }
}
},
"Register": {
"title": "Registrera konto",
"heading": "Nytt konto",
"cta": "Skapa konto",
- "somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare."
+ "somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare.",
+ "FieldErrors": {
+ "firstNameRequired": "Förnamn krävs",
+ "lastNameRequired": "Efternamn krävs",
+ "emailRequired": "E-postadress krävs",
+ "emailInvalid": "Ange en giltig e-postadress",
+ "passwordRequired": "Lösenord krävs",
+ "passwordTooSmall": "Lösenordet måste vara minst {minLength, plural, =1 {1 tecken} other {# tecken}} långt",
+ "passwordLowercaseRequired": "Lösenordet måste innehålla minst en liten bokstav",
+ "passwordUppercaseRequired": "Lösenordet måste innehålla minst en stor bokstav",
+ "passwordNumberRequired": "Lösenordet måste innehålla minst {minNumbers, plural, =1 {ett nummer} other {# nummer}}",
+ "passwordSpecialCharacterRequired": "Lösenordet måste innehålla minst ett specialtecken",
+ "passwordsMustMatch": "Lösenorden stämmer inte överens",
+ "addressLine1Required": "Adresslinje 1 krävs",
+ "cityRequired": "Stad krävs",
+ "countryRequired": "Land krävs",
+ "stateRequired": "Stat/provins krävs",
+ "postalCodeRequired": "Postnummer krävs"
+ }
}
},
"Faceted": {
@@ -188,6 +226,15 @@
"somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare.",
"EmptyState": {
"title": "Du har inga adresser"
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Förnamn krävs",
+ "lastNameRequired": "Efternamn krävs",
+ "addressLine1Required": "Adresslinje 1 krävs",
+ "cityRequired": "Stad krävs",
+ "countryRequired": "Land krävs",
+ "stateRequired": "Stat/provins krävs",
+ "postalCodeRequired": "Postnummer krävs"
}
},
"Settings": {
@@ -205,6 +252,23 @@
"label": "Prenumerera på vårt nyhetsbrev.",
"marketingPreferencesUpdated": "Marknadsföringsinställningarna har uppdaterats framgångsrikt!",
"somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare."
+ },
+ "FieldErrors": {
+ "firstNameRequired": "Förnamn krävs",
+ "firstNameTooSmall": "Förnamnet måste vara minst 2 tecken långt",
+ "lastNameRequired": "Efternamn krävs",
+ "lastNameTooSmall": "Efternamnet måste vara minst två tecken långt",
+ "emailRequired": "E-postadress krävs",
+ "emailInvalid": "Ange en giltig e-postadress",
+ "currentPasswordRequired": "Nuvarande lösenord krävs",
+ "passwordRequired": "Lösenord krävs",
+ "passwordTooSmall": "Lösenordet måste vara minst {minLength, plural, =1 {1 tecken} other {# tecken}} långt",
+ "passwordLowercaseRequired": "Lösenordet måste innehålla minst en liten bokstav",
+ "passwordUppercaseRequired": "Lösenordet måste innehålla minst en stor bokstav",
+ "passwordNumberRequired": "Lösenordet måste innehålla minst {minNumbers, plural, =1 {ett nummer} other {# nummer}}",
+ "passwordSpecialCharacterRequired": "Lösenordet måste innehålla minst ett specialtecken",
+ "passwordsMustMatch": "Lösenorden stämmer inte överens",
+ "confirmPasswordRequired": "Bekräfta ditt lösenord"
}
}
},
@@ -304,8 +368,11 @@
"cartCombined": "Vi märkte att du hade varor sparade i en tidigare kundvagn, så vi har lagt till dem i din nuvarande kundvagn åt dig.",
"cartRestored": "Du startade en kundvagn på en annan enhet, och vi har återställt den här så att du kan fortsätta där du slutade.",
"cartUpdateInProgress": "Du har en pågående kundvagnsuppdatering. Är du säker på att du vill lämna den här sidan? Dina ändringar kan gå förlorade.",
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
+ "originalPrice": "Ursprungligt pris var {price}.",
+ "currentPrice": "Nuvarande pris är {price}.",
+ "quantityReadyToShip": "{quantity, number} klara för leverans",
+ "quantityOnBackorder": "{quantity, number} kommer att vara restnoterade",
+ "partiallyAvailable": "Endast {quantity, number} tillgängligt",
"CheckoutSummary": {
"title": "Summering",
"subTotal": "Delsumma",
@@ -335,7 +402,8 @@
"updateShipping": "Uppdatera frakt",
"addShipping": "Lägg till frakt",
"cartNotFound": "Ett fel uppstod när er varukorg hämtades",
- "noShippingOptions": "Det finns inga tillgängliga fraktalternativ för din adress"
+ "noShippingOptions": "Det finns inga tillgängliga fraktalternativ för din adress",
+ "countryRequired": "Land krävs"
}
},
"GiftCertificate": {
@@ -395,6 +463,8 @@
"additionalInformation": "Ytterligare information",
"currentStock": "{quantity, number} i lager",
"backorderQuantity": "{quantity, number} kommer att vara restnoterade",
+ "loadingMoreImages": "Loading more images",
+ "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
"Submit": {
"addToCart": "Lägg till i kundvagn",
"outOfStock": "Ej i lager",
@@ -427,13 +497,24 @@
"button": "Skriva en recension",
"title": "Skriva en recension",
"submit": "Skicka in",
+ "cancel": "Annullera",
"ratingLabel": "Bedömning",
"titleLabel": "Rubrik",
"reviewLabel": "Recension",
"nameLabel": "Namn",
"emailLabel": "E-post",
"successMessage": "Din recension har skickats in!",
- "somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare."
+ "somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare.",
+ "FieldErrors": {
+ "titleRequired": "Rubrik krävs",
+ "authorRequired": "Namn krävs",
+ "emailRequired": "E-postadress krävs",
+ "emailInvalid": "Ange en giltig e-postadress",
+ "textRequired": "Granskning krävs",
+ "ratingRequired": "Betyg krävs",
+ "ratingTooSmall": "Betyget måste vara minst 1",
+ "ratingTooLarge": "Betyget får vara högst 5"
+ }
}
}
},
@@ -515,7 +596,8 @@
"description": "Håll dig uppdaterad med de senaste nyheterna och erbjudandena från vår butik.",
"subscribedToNewsletter": "Du prenumererar nu på vårt nyhetsbrev!",
"Errors": {
- "invalidEmail": "Vänligen ange en giltig e-postadress",
+ "emailRequired": "E-postadress krävs",
+ "invalidEmail": "Ange en giltig e-postadress",
"somethingWentWrong": "Någonting gick fel. Vänligen försök igen senare."
}
},
@@ -559,9 +641,9 @@
}
},
"Price": {
- "originalPrice": "Original price was {price}.",
- "currentPrice": "Current price is {price}.",
- "range": "Price from {minValue} to {maxValue}."
+ "originalPrice": "Ursprungligt pris var {price}.",
+ "currentPrice": "Nuvarande pris är {price}.",
+ "range": "Pris från {minValue} till {maxValue}."
}
},
"GiftCertificates": {
@@ -574,7 +656,7 @@
"title": "Kontrollera saldot",
"description": "Du kan kontrollera saldot och få information om ditt presentkort genom att skriva in koden i rutan nedan.",
"inputLabel": "Kod",
- "inputPlaceholder": "xxx-xxx-xxx-xxx",
+ "inputPlaceholder": "XXX-XXX-XXX-XXX",
"purchasedDateLabel": "Köpt",
"senderLabel": "Från",
"Errors": {
@@ -607,15 +689,25 @@
"expiryCheckboxLabel": "Jag bekräftar att detta presentkort kommer att upphöra att gälla den {expiryDate}",
"ctaLabel": "Lägg till i kundvagn",
"Errors": {
- "amountRequired": "Var god välj eller ange ett presentkortsbelopp.",
- "amountInvalid": "Var god välj ett giltigt presentkortsbelopp.",
- "amountOutOfRange": "Ange ett belopp mellan {minAmount} och {maxAmount}.",
- "unexpectedSettingsError": "Ett oväntat fel inträffade när presentkortets inställningar hämtades. Försök igen senare."
+ "amountRequired": "Var god välj eller ange ett presentkortsbelopp",
+ "amountInvalid": "Välj ett giltigt presentkortsbelopp.",
+ "amountOutOfRange": "Ange ett belopp mellan {minAmount} och {maxAmount}",
+ "unexpectedSettingsError": "Ett oväntat fel inträffade när presentkortets inställningar hämtades. Försök igen senare.",
+ "senderNameRequired": "Ditt namn krävs",
+ "senderEmailRequired": "Din e-postadress krävs",
+ "recipientNameRequired": "Mottagarens namn är obligatoriskt",
+ "recipientEmailRequired": "Mottagarens e-postadress krävs",
+ "emailInvalid": "Ange en giltig e-postadress",
+ "checkboxRequired": "Du måste markera den här rutan för att fortsätta"
}
}
}
},
"Form": {
- "optional": "frivillig"
+ "optional": "frivillig",
+ "Errors": {
+ "invalidInput": "Kontrollera det som angetts och försök igen",
+ "invalidFormat": "Det inmatade värdet stämmer inte överens med det format som krävs"
+ }
}
}
From 7889cfa9cf937e1bf80f0c443efbfb16010b137e Mon Sep 17 00:00:00 2001
From: Jorge Moya
Date: Wed, 18 Feb 2026 12:25:42 -0600
Subject: [PATCH 14/17] fix(core): preview deployments now use correct
metadataBase (#2890)
* fix(core): preview deployments now use correct metadataBase
* fix: lint issue
* fix: use URL.canParse
* chore: update changeset
---
.changeset/new-onions-flash.md | 46 +++++++++++++++++++++++++++-------
core/app/[locale]/layout.tsx | 13 +++++++++-
core/lib/seo/canonical.ts | 5 +++-
3 files changed, 53 insertions(+), 11 deletions(-)
diff --git a/.changeset/new-onions-flash.md b/.changeset/new-onions-flash.md
index 7bc9afcce..15e0f6ec6 100644
--- a/.changeset/new-onions-flash.md
+++ b/.changeset/new-onions-flash.md
@@ -2,25 +2,53 @@
"@bigcommerce/catalyst-core": patch
---
-Add canonical URLs and hreflang alternates for SEO. Pages now set `alternates.canonical` and `alternates.languages` in `generateMetadata` via the new `getMetadataAlternates` helper in `core/lib/seo/canonical.ts`. The helper fetches the vanity URL via GraphQL (`site.settings.url.vanityUrl`) and is cached per request. The default locale uses no path prefix; other locales use `/{locale}/path`. The root locale layout sets `metadataBase` to the configured vanity URL so canonical URLs resolve correctly.
+Add canonical URLs and hreflang alternates for SEO. Pages now set `alternates.canonical` and `alternates.languages` in `generateMetadata` via the new `getMetadataAlternates` helper in `core/lib/seo/canonical.ts`. The helper fetches the vanity URL via GraphQL (`site.settings.url.vanityUrl`) and is cached per request. The default locale uses no path prefix; other locales use `/{locale}/path`. The root locale layout sets `metadataBase` to the configured vanity URL so canonical URLs resolve correctly. On Vercel preview deployments (`VERCEL_ENV=preview`), `metadataBase` and canonical/hreflang URLs use `VERCEL_URL` instead of the production vanity URL to prevent preview environments from generating SEO metadata pointing to production.
## Migration steps
### Step 1: Root layout metadata base
-The root locale layout now sets `metadataBase` from the vanity URL fetched via GraphQL. This is already included in the `RootLayoutMetadataQuery`.
+The root locale layout now sets `metadataBase` from the vanity URL fetched via GraphQL. On Vercel preview deployments, `VERCEL_URL` is used instead so preview environments don't point to production. `URL.canParse` guards against malformed URLs.
Update `core/app/[locale]/layout.tsx`:
```diff
+ const vanityUrl = data.site.settings?.url.vanityUrl;
++
++ // Use preview deployment URL so metadataBase (canonical, og:url) points at the preview, not production.
++ let baseUrl: URL | undefined;
++ const previewUrl =
++ process.env.VERCEL_ENV === 'preview' ? `https://${process.env.VERCEL_URL}` : undefined;
++
++ if (previewUrl && URL.canParse(previewUrl)) {
++ baseUrl = new URL(previewUrl);
++ } else if (vanityUrl && URL.canParse(vanityUrl)) {
++ baseUrl = new URL(vanityUrl);
++ }
+
return {
-+ metadataBase: vanityUrl ? new URL(vanityUrl) : undefined,
++ metadataBase: baseUrl,
title: {
```
-### Step 2: GraphQL fragment updates
+### Step 2: Canonical/hreflang base URL for preview environments
+
+The `getMetadataAlternates` function in `core/lib/seo/canonical.ts` now checks for a Vercel preview URL before falling back to the GraphQL vanity URL. `URL.canParse` guards against malformed URLs.
+
+Update `core/lib/seo/canonical.ts`:
+
+```diff
+ export async function getMetadataAlternates(options: CanonicalUrlOptions) {
+ const { path, locale, includeAlternates = true } = options;
+
+- const baseUrl = await getVanityUrl();
++ // Use preview deployment URL so canonical/hreflang URLs point at the preview, not production.
++ const previewUrl =
++ process.env.VERCEL_ENV === 'preview' ? `https://${process.env.VERCEL_URL}` : undefined;
++ const baseUrl = previewUrl && URL.canParse(previewUrl) ? previewUrl : await getVanityUrl();
+```
+
+### Step 3: GraphQL fragment updates
Add the `path` field to brand, blog post, and product queries so metadata can build canonical URLs.
@@ -54,7 +82,7 @@ Update `core/app/[locale]/(default)/product/[slug]/page-data.ts` (in the metadat
defaultImage {
```
-### Step 3: Page metadata alternates
+### Step 4: Page metadata alternates
Add the `getMetadataAlternates` import and set `alternates` in `generateMetadata` for each page. The function is async and must be awaited. Ensure `core/lib/seo/canonical.ts` exists (it is included in this release).
@@ -94,7 +122,7 @@ For entity pages (product, category, brand, blog, blog post, webpage), add the i
}
```
-### Step 4: Gift certificates pages
+### Step 5: Gift certificates pages
Update `core/app/[locale]/(default)/gift-certificates/page.tsx`:
@@ -142,7 +170,7 @@ Add `generateMetadata` to `core/app/[locale]/(default)/gift-certificates/purchas
+ }
```
-### Step 5: Contact page
+### Step 6: Contact page
Update `core/app/[locale]/(default)/webpages/[id]/contact/page.tsx`:
@@ -164,7 +192,7 @@ Update `core/app/[locale]/(default)/webpages/[id]/contact/page.tsx`:
}
```
-### Step 6: Public wishlist page
+### Step 7: Public wishlist page
Update `core/app/[locale]/(default)/wishlist/[token]/page.tsx`:
@@ -181,7 +209,7 @@ Update `core/app/[locale]/(default)/wishlist/[token]/page.tsx`:
}
```
-### Step 7: Compare page
+### Step 8: Compare page
Update `core/app/[locale]/(default)/compare/page.tsx`:
diff --git a/core/app/[locale]/layout.tsx b/core/app/[locale]/layout.tsx
index ae7642bd3..f0a08d7f3 100644
--- a/core/app/[locale]/layout.tsx
+++ b/core/app/[locale]/layout.tsx
@@ -73,8 +73,19 @@ export async function generateMetadata(): Promise {
const vanityUrl = data.site.settings?.url.vanityUrl;
+ // Use preview deployment URL so metadataBase (canonical, og:url) points at the preview, not production.
+ let baseUrl: URL | undefined;
+ const previewUrl =
+ process.env.VERCEL_ENV === 'preview' ? `https://${process.env.VERCEL_URL}` : undefined;
+
+ if (previewUrl && URL.canParse(previewUrl)) {
+ baseUrl = new URL(previewUrl);
+ } else if (vanityUrl && URL.canParse(vanityUrl)) {
+ baseUrl = new URL(vanityUrl);
+ }
+
return {
- metadataBase: vanityUrl ? new URL(vanityUrl) : undefined,
+ metadataBase: baseUrl,
title: {
template: `%s - ${storeName}`,
default: pageTitle || storeName,
diff --git a/core/lib/seo/canonical.ts b/core/lib/seo/canonical.ts
index 03f9cac3f..dd1573947 100644
--- a/core/lib/seo/canonical.ts
+++ b/core/lib/seo/canonical.ts
@@ -63,7 +63,10 @@ const getVanityUrl = cache(async () => {
export async function getMetadataAlternates(options: CanonicalUrlOptions) {
const { path, locale, includeAlternates = true } = options;
- const baseUrl = await getVanityUrl();
+ // Use preview deployment URL so canonical/hreflang URLs point at the preview, not production.
+ const previewUrl =
+ process.env.VERCEL_ENV === 'preview' ? `https://${process.env.VERCEL_URL}` : undefined;
+ const baseUrl = previewUrl && URL.canParse(previewUrl) ? previewUrl : await getVanityUrl();
const canonical = buildLocalizedUrl(baseUrl, path, locale);
From a161583fee1b6e7e3f718c2e6f705ea822865025 Mon Sep 17 00:00:00 2001
From: Jorge Moya
Date: Wed, 18 Feb 2026 13:59:18 -0600
Subject: [PATCH 15/17] feat(ci): enable unlighthouse performance audits for
vercel (#2882)
* feat(ci): enable unlighthouse performance audits for vercel
Re-enable the performance category in Unlighthouse with mitigations for
hardware throttling: maxConcurrency=1 and samples=5 (median smoothing
absorbs cold start outliers across all discovered pages without needing
an explicit warm-up step). Rename artifacts with a "vercel" label for
future cross-platform comparison.
CATALYST-1768
Co-Authored-By: Claude Opus 4.6
* chore: revert samples to 3
* chore: add concurrency to speed tests
* fix: target specific PLP and PDP pages to prevent wasted runtime
* fix: change PLP category to bath
* fix: expand report
* chore: test concurrency and all routes
* fix: fixed paths, multiple samples, with concurrency
* fix: run all pages, concurrency enabled, 1 sample size
* fix: add sample size of 3
* feat: add dynamic sampling
* fix: split brands and categories
* fix: update excluded routes
* fix: excluded paths
* fix: exclude other sites
* fix: disable throttling
* chore: update dynamic sampling
* fix: remove brands from custom sampling since it should be picked up automatically
* chore: limit concurrency
* chore: remove concurrency limit, no visible change
---------
Co-authored-by: Claude Opus 4.6
---
.github/workflows/regression-tests.yml | 2 +-
unlighthouse.config.ts | 48 +++++++++++++++++++-------
2 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/.github/workflows/regression-tests.yml b/.github/workflows/regression-tests.yml
index ef81ebc18..3b4e8d4c1 100644
--- a/.github/workflows/regression-tests.yml
+++ b/.github/workflows/regression-tests.yml
@@ -38,6 +38,6 @@ jobs:
if: failure() || success()
uses: actions/upload-artifact@v4
with:
- name: unlighthouse-${{ matrix.device }}-report
+ name: unlighthouse-vercel-${{ matrix.device }}-report
path: './.unlighthouse/'
include-hidden-files: 'true'
diff --git a/unlighthouse.config.ts b/unlighthouse.config.ts
index e323a87b5..796466a4c 100644
--- a/unlighthouse.config.ts
+++ b/unlighthouse.config.ts
@@ -1,27 +1,51 @@
-
-import type { UserConfig } from 'unlighthouse';
+import type { UserConfig } from "unlighthouse";
export default {
ci: {
buildStatic: true,
- // Disabling the budget so we can audit and fix the issues first
+ reporter: "jsonExpanded",
budget: {
// "best-practices": 100,
// "accessibility": 100,
// "seo": 100,
+ // performance: 80,
+ },
+ },
+ scanner: {
+ // Run each page multiple times and use the median to absorb cold start
+ // outliers across all discovered pages.
+ samples: 3,
+ dynamicSampling: 5,
+ exclude: [
+ "/bundleb2b/",
+ "/invoices/",
+ "/bath/*/*",
+ "/garden/*/*",
+ "/kitchen/*/*",
+ "/publications/*/*",
+ "/early-access/*/*",
+ "/digital-test-product/",
+ "/blog/\\?tag=*",
+ ],
+ customSampling: {
+ "/smith-journal-13/|/dustpan-brush/|/utility-caddy/|/canvas-laundry-cart/|/laundry-detergent/|/tiered-wire-basket/|/oak-cheese-grater/|/1-l-le-parfait-jar/|/chemex-coffeemaker-3-cup/|/sample-able-brewing-system/|/orbit-terrarium-small/|/orbit-terrarium-large/|/fog-linen-chambray-towel-beige-stripe/|/zz-plant/":
+ { name: "PDP" },
+ "/shop-all/|/bath/|/garden/|/kitchen/|/publications/|/early-access/": {
+ name: "PLP",
+ },
},
- },
+ // Disable throttling to avoid issues with cold start and cold cache.
+ throttle: false,
+ },
lighthouseOptions: {
- // Disabling performance tests because lighthouse utilizes hardware throttling. This affects concurrently running tests which might lead to false positives.
- // The best way to truly measure performance is to use real user metrics – Vercel's Speed Insights is a great tool for that.
- onlyCategories: ['best-practices', 'accessibility', 'seo'],
+ onlyCategories: ["best-practices", "accessibility", "seo", "performance"],
skipAudits: [
// Disabling `is-crawlable` as it's more relevant for production sites.
- 'is-crawlable',
+ "is-crawlable",
// Disabling third-party cookies because the only third-party cookies we have is provided through Cloudflare for our CDN, which is not relevant for our audits.
- 'third-party-cookies',
+ "third-party-cookies",
// Disabling inspector issues as it's only providing third-party cookie issues, which are not relevant for our audits.
- 'inspector-issues',
- ]
- }
+ "inspector-issues",
+ ],
+ },
} satisfies UserConfig;
From 46ee3de640f030be56111c668102bbeeb961b4a4 Mon Sep 17 00:00:00 2001
From: Jorge Moya
Date: Wed, 25 Feb 2026 09:02:07 -0600
Subject: [PATCH 16/17] fix(core): conditionally include optional SEO metadata
(#2898)
* fix(core): conditionally include optional SEO metadata
* fix: remove new line in product meta description
---
.changeset/quiet-tags-spread.md | 77 +++++++++++++++++++
.../(default)/(faceted)/brand/[slug]/page.tsx | 6 +-
.../(faceted)/category/[slug]/page.tsx | 4 +-
.../[locale]/(default)/blog/[blogId]/page.tsx | 4 +-
core/app/[locale]/(default)/blog/page.tsx | 10 ++-
.../(default)/product/[slug]/page.tsx | 17 ++--
.../(default)/webpages/[id]/contact/page.tsx | 8 +-
.../(default)/webpages/[id]/normal/page.tsx | 4 +-
8 files changed, 102 insertions(+), 28 deletions(-)
create mode 100644 .changeset/quiet-tags-spread.md
diff --git a/.changeset/quiet-tags-spread.md b/.changeset/quiet-tags-spread.md
new file mode 100644
index 000000000..7a3a75f8f
--- /dev/null
+++ b/.changeset/quiet-tags-spread.md
@@ -0,0 +1,77 @@
+---
+"@bigcommerce/catalyst-core": patch
+---
+
+Conditionally include optional SEO metadata fields in `generateMetadata` across page files. Fields `description`, `keywords`, `alternates`, and `openGraph` are now only included in the returned metadata object when they have a value, using spread syntax (`...(value && { key: value })`). Previously, these fields were always set — potentially assigning `null` or an empty string — which could cause Next.js to render empty `` tags.
+
+## Migration steps
+
+Update `generateMetadata` in the following pages to use conditional spread syntax for optional metadata fields:
+
+### brand, category, webpages (contact + normal)
+
+```diff
+ return {
+ title: pageTitle || entity.name,
+- description: metaDescription,
+- keywords: metaKeywords ? metaKeywords.split(',') : null,
++ ...(metaDescription && { description: metaDescription }),
++ ...(metaKeywords && { keywords: metaKeywords.split(',') }),
+ };
+```
+
+For `brand/[slug]/page.tsx`, also guard the `alternates` field:
+
+```diff
+- alternates: await getMetadataAlternates({ path: brand.path, locale }),
++ ...(brand.path && { alternates: await getMetadataAlternates({ path: brand.path, locale }) }),
+```
+
+### blog/[blogId]/page.tsx
+
+```diff
+ return {
+ title: pageTitle || blogPost.name,
+- description: metaDescription,
+- keywords: metaKeywords ? metaKeywords.split(',') : null,
++ ...(metaDescription && { description: metaDescription }),
++ ...(metaKeywords && { keywords: metaKeywords.split(',') }),
+ ...(blogPost.path && {
+ alternates: await getMetadataAlternates({ path: blogPost.path, locale }),
+ }),
+ };
+```
+
+### product/[slug]/page.tsx
+
+```diff
+- keywords: metaKeywords ? metaKeywords.split(',') : null,
++ ...(metaKeywords && { keywords: metaKeywords.split(',') }),
+- openGraph: url
+- ? {
+- images: [{ url, alt }],
+- }
+- : null,
++ ...(url && { openGraph: { images: [{ url, alt }] } }),
+```
+
+### blog/page.tsx
+
+Extract the description to a variable and spread conditionally:
+
+```diff
++ const description =
++ blog?.description && blog.description.length > 150
++ ? `${blog.description.substring(0, 150)}...`
++ : blog?.description;
++
+ return {
+ title: blog?.name ?? t('title'),
+- description:
+- blog?.description && blog.description.length > 150
+- ? `${blog.description.substring(0, 150)}...`
+- : blog?.description,
++ ...(description && { description }),
+ ...(blog?.path && { alternates: await getMetadataAlternates({ path: blog.path, locale }) }),
+ };
+```
diff --git a/core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx b/core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx
index 163419493..4278def31 100644
--- a/core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx
+++ b/core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx
@@ -83,9 +83,9 @@ export async function generateMetadata(props: Props): Promise {
return {
title: pageTitle || brand.name,
- description: metaDescription,
- keywords: metaKeywords ? metaKeywords.split(',') : null,
- alternates: await getMetadataAlternates({ path: brand.path, locale }),
+ ...(metaDescription && { description: metaDescription }),
+ ...(metaKeywords && { keywords: metaKeywords.split(',') }),
+ ...(brand.path && { alternates: await getMetadataAlternates({ path: brand.path, locale }) }),
};
}
diff --git a/core/app/[locale]/(default)/(faceted)/category/[slug]/page.tsx b/core/app/[locale]/(default)/(faceted)/category/[slug]/page.tsx
index 3471282dd..ee143281b 100644
--- a/core/app/[locale]/(default)/(faceted)/category/[slug]/page.tsx
+++ b/core/app/[locale]/(default)/(faceted)/category/[slug]/page.tsx
@@ -88,8 +88,8 @@ export async function generateMetadata(props: Props): Promise {
return {
title: pageTitle || category.name,
- description: metaDescription,
- keywords: metaKeywords ? metaKeywords.split(',') : null,
+ ...(metaDescription && { description: metaDescription }),
+ ...(metaKeywords && { keywords: metaKeywords.split(',') }),
...(categoryPath && {
alternates: await getMetadataAlternates({ path: categoryPath, locale }),
}),
diff --git a/core/app/[locale]/(default)/blog/[blogId]/page.tsx b/core/app/[locale]/(default)/blog/[blogId]/page.tsx
index 35ba4ffa9..6b8da4501 100644
--- a/core/app/[locale]/(default)/blog/[blogId]/page.tsx
+++ b/core/app/[locale]/(default)/blog/[blogId]/page.tsx
@@ -34,8 +34,8 @@ export async function generateMetadata({ params }: Props): Promise {
return {
title: pageTitle || blogPost.name,
- description: metaDescription,
- keywords: metaKeywords ? metaKeywords.split(',') : null,
+ ...(metaDescription && { description: metaDescription }),
+ ...(metaKeywords && { keywords: metaKeywords.split(',') }),
...(blogPost.path && {
alternates: await getMetadataAlternates({ path: blogPost.path, locale }),
}),
diff --git a/core/app/[locale]/(default)/blog/page.tsx b/core/app/[locale]/(default)/blog/page.tsx
index e960967c5..1b8d90cf9 100644
--- a/core/app/[locale]/(default)/blog/page.tsx
+++ b/core/app/[locale]/(default)/blog/page.tsx
@@ -31,12 +31,14 @@ export async function generateMetadata({ params }: Props): Promise {
const t = await getTranslations({ locale, namespace: 'Blog' });
const blog = await getBlog();
+ const description =
+ blog?.description && blog.description.length > 150
+ ? `${blog.description.substring(0, 150)}...`
+ : blog?.description;
+
return {
title: blog?.name ?? t('title'),
- description:
- blog?.description && blog.description.length > 150
- ? `${blog.description.substring(0, 150)}...`
- : blog?.description,
+ ...(description && { description }),
...(blog?.path && { alternates: await getMetadataAlternates({ path: blog.path, locale }) }),
};
}
diff --git a/core/app/[locale]/(default)/product/[slug]/page.tsx b/core/app/[locale]/(default)/product/[slug]/page.tsx
index 5f31e4dad..c1e8a96bf 100644
--- a/core/app/[locale]/(default)/product/[slug]/page.tsx
+++ b/core/app/[locale]/(default)/product/[slug]/page.tsx
@@ -55,19 +55,12 @@ export async function generateMetadata({ params }: Props): Promise {
return {
title: pageTitle || product.name,
- description: metaDescription || `${product.plainTextDescription.slice(0, 150)}...`,
- keywords: metaKeywords ? metaKeywords.split(',') : null,
+ description:
+ metaDescription ||
+ `${product.plainTextDescription.replaceAll(/\s+/g, ' ').trim().slice(0, 150)}...`,
+ ...(metaKeywords && { keywords: metaKeywords.split(',') }),
alternates: await getMetadataAlternates({ path: product.path, locale }),
- openGraph: url
- ? {
- images: [
- {
- url,
- alt,
- },
- ],
- }
- : null,
+ ...(url && { openGraph: { images: [{ url, alt }] } }),
};
}
diff --git a/core/app/[locale]/(default)/webpages/[id]/contact/page.tsx b/core/app/[locale]/(default)/webpages/[id]/contact/page.tsx
index e053978db..b8d1f2e75 100644
--- a/core/app/[locale]/(default)/webpages/[id]/contact/page.tsx
+++ b/core/app/[locale]/(default)/webpages/[id]/contact/page.tsx
@@ -160,9 +160,11 @@ export async function generateMetadata({ params }: Props): Promise {
return {
title: pageTitle || webpage.title,
- description: metaDescription,
- keywords: metaKeywords ? metaKeywords.split(',') : null,
- alternates: await getMetadataAlternates({ path: webpage.path, locale }),
+ ...(metaDescription && { description: metaDescription }),
+ ...(metaKeywords && { keywords: metaKeywords.split(',') }),
+ ...(webpage.path && {
+ alternates: await getMetadataAlternates({ path: webpage.path, locale }),
+ }),
};
}
diff --git a/core/app/[locale]/(default)/webpages/[id]/normal/page.tsx b/core/app/[locale]/(default)/webpages/[id]/normal/page.tsx
index 6406c381d..a222ea18c 100644
--- a/core/app/[locale]/(default)/webpages/[id]/normal/page.tsx
+++ b/core/app/[locale]/(default)/webpages/[id]/normal/page.tsx
@@ -67,8 +67,8 @@ export async function generateMetadata({ params }: Props): Promise {
return {
title: pageTitle || webpage.title,
- description: metaDescription,
- keywords: metaKeywords ? metaKeywords.split(',') : null,
+ ...(metaDescription && { description: metaDescription }),
+ ...(metaKeywords && { keywords: metaKeywords.split(',') }),
...(pagePath && { alternates: await getMetadataAlternates({ path: pagePath, locale }) }),
};
}
From 8d128fc75006ef8ab330e3597bfcf15cdc70da71 Mon Sep 17 00:00:00 2001
From: bc-svc-local <102379007+bc-svc-local@users.noreply.github.com>
Date: Wed, 25 Feb 2026 16:19:41 +0100
Subject: [PATCH 17/17] Update translations (#2897)
* feat(other): LOCAL-1444 delivery translation
* chore(core): create translations patch
---------
Co-authored-by: bc-svc-local
---
.changeset/translations-patch-2487e2ac.md | 5 +++++
core/messages/da.json | 4 ++--
core/messages/de.json | 4 ++--
core/messages/es-419.json | 4 ++--
core/messages/es-AR.json | 4 ++--
core/messages/es-CL.json | 4 ++--
core/messages/es-CO.json | 4 ++--
core/messages/es-LA.json | 4 ++--
core/messages/es-MX.json | 4 ++--
core/messages/es-PE.json | 4 ++--
core/messages/es.json | 4 ++--
core/messages/fr.json | 4 ++--
core/messages/it.json | 4 ++--
core/messages/ja.json | 4 ++--
core/messages/nl.json | 4 ++--
core/messages/no.json | 4 ++--
core/messages/sv.json | 4 ++--
17 files changed, 37 insertions(+), 32 deletions(-)
create mode 100644 .changeset/translations-patch-2487e2ac.md
diff --git a/.changeset/translations-patch-2487e2ac.md b/.changeset/translations-patch-2487e2ac.md
new file mode 100644
index 000000000..ad17b2636
--- /dev/null
+++ b/.changeset/translations-patch-2487e2ac.md
@@ -0,0 +1,5 @@
+---
+"@bigcommerce/catalyst-core": patch
+---
+
+Update translations.
diff --git a/core/messages/da.json b/core/messages/da.json
index 0f571c362..8bd50c727 100644
--- a/core/messages/da.json
+++ b/core/messages/da.json
@@ -463,8 +463,8 @@
"additionalInformation": "Yderligere oplysninger",
"currentStock": "{antal, number} på lager",
"backorderQuantity": "{antal, number} vil være i restordre",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Indlæser flere billeder",
+ "imagesLoaded": "{count, plural, =1 {1 yderligere billede indlæst} other {# yderligere billeder indlæst}}",
"Submit": {
"addToCart": "Føj til kurv",
"outOfStock": "Udsolgt",
diff --git a/core/messages/de.json b/core/messages/de.json
index 8a7db06ad..1a83921ca 100644
--- a/core/messages/de.json
+++ b/core/messages/de.json
@@ -463,8 +463,8 @@
"additionalInformation": "Weitere Informationen",
"currentStock": "{quantity, number} auf Lager",
"backorderQuantity": "{quantity, number} wird nachbestellt",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Weitere Bilder werden geladen",
+ "imagesLoaded": "{count, plural, =1 {1 weiteres Bild geladen, } other {# weitere Bilder geladen, }}",
"Submit": {
"addToCart": "Zum Warenkorb hinzufügen",
"outOfStock": "Kein Lagerbestand",
diff --git a/core/messages/es-419.json b/core/messages/es-419.json
index 93e494019..43924c445 100644
--- a/core/messages/es-419.json
+++ b/core/messages/es-419.json
@@ -463,8 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Cargando más imágenes",
+ "imagesLoaded": "{count, plural, =1 {1 imagen más cargada} other {# más imágenes cargadas}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
diff --git a/core/messages/es-AR.json b/core/messages/es-AR.json
index 93e494019..43924c445 100644
--- a/core/messages/es-AR.json
+++ b/core/messages/es-AR.json
@@ -463,8 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Cargando más imágenes",
+ "imagesLoaded": "{count, plural, =1 {1 imagen más cargada} other {# más imágenes cargadas}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
diff --git a/core/messages/es-CL.json b/core/messages/es-CL.json
index 93e494019..43924c445 100644
--- a/core/messages/es-CL.json
+++ b/core/messages/es-CL.json
@@ -463,8 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Cargando más imágenes",
+ "imagesLoaded": "{count, plural, =1 {1 imagen más cargada} other {# más imágenes cargadas}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
diff --git a/core/messages/es-CO.json b/core/messages/es-CO.json
index 93e494019..43924c445 100644
--- a/core/messages/es-CO.json
+++ b/core/messages/es-CO.json
@@ -463,8 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Cargando más imágenes",
+ "imagesLoaded": "{count, plural, =1 {1 imagen más cargada} other {# más imágenes cargadas}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
diff --git a/core/messages/es-LA.json b/core/messages/es-LA.json
index 93e494019..43924c445 100644
--- a/core/messages/es-LA.json
+++ b/core/messages/es-LA.json
@@ -463,8 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Cargando más imágenes",
+ "imagesLoaded": "{count, plural, =1 {1 imagen más cargada} other {# más imágenes cargadas}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
diff --git a/core/messages/es-MX.json b/core/messages/es-MX.json
index 93e494019..43924c445 100644
--- a/core/messages/es-MX.json
+++ b/core/messages/es-MX.json
@@ -463,8 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Cargando más imágenes",
+ "imagesLoaded": "{count, plural, =1 {1 imagen más cargada} other {# más imágenes cargadas}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
diff --git a/core/messages/es-PE.json b/core/messages/es-PE.json
index 93e494019..43924c445 100644
--- a/core/messages/es-PE.json
+++ b/core/messages/es-PE.json
@@ -463,8 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en stock",
"backorderQuantity": "{cantidad, número} estará en espera",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Cargando más imágenes",
+ "imagesLoaded": "{count, plural, =1 {1 imagen más cargada} other {# más imágenes cargadas}}",
"Submit": {
"addToCart": "Agregar al carrito",
"outOfStock": "Agotado/a",
diff --git a/core/messages/es.json b/core/messages/es.json
index 507e02c4b..edd2b00ab 100644
--- a/core/messages/es.json
+++ b/core/messages/es.json
@@ -463,8 +463,8 @@
"additionalInformation": "Información adicional",
"currentStock": "{cantidad, número} en existencias",
"backorderQuantity": "{cantidad, número} en pedidos pendientes",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Cargando más imágenes",
+ "imagesLoaded": "{count, plural, =1 {1 imagen más cargada} other {# imágenes más cargadas}}",
"Submit": {
"addToCart": "Añadir al carrito",
"outOfStock": "Sin existencias",
diff --git a/core/messages/fr.json b/core/messages/fr.json
index 9e3ba28a7..cc4aea4b5 100644
--- a/core/messages/fr.json
+++ b/core/messages/fr.json
@@ -463,8 +463,8 @@
"additionalInformation": "Informations supplémentaires",
"currentStock": "{quantity, number} en stock",
"backorderQuantity": "{quantité, nombre} en attente de réapprovisionnement",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Chargement de plus d'images",
+ "imagesLoaded": "{count, plural, =1 {1 image supplémentaire chargée} other {# images supplémentaires chargées}}",
"Submit": {
"addToCart": "Ajouter au panier",
"outOfStock": "En rupture de stock",
diff --git a/core/messages/it.json b/core/messages/it.json
index 9d49e830c..e47aa82c0 100644
--- a/core/messages/it.json
+++ b/core/messages/it.json
@@ -463,8 +463,8 @@
"additionalInformation": "Informazioni aggiuntive",
"currentStock": "{quantità, numero} in magazzino",
"backorderQuantity": "{quantity, number} sarà in arretrato",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Caricamento di altre immagini",
+ "imagesLoaded": "{count, plural, =1 {1 altra immagine caricata} other {# altre immagini caricate}}",
"Submit": {
"addToCart": "Aggiungi al carrello",
"outOfStock": "Esaurito",
diff --git a/core/messages/ja.json b/core/messages/ja.json
index ff94c4325..5a2fa86d4 100644
--- a/core/messages/ja.json
+++ b/core/messages/ja.json
@@ -463,8 +463,8 @@
"additionalInformation": "追加情報",
"currentStock": "{quantity, number} 個の在庫あり",
"backorderQuantity": "{quantity, number} はバックオーダーになります",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "さらに画像を読み込んでいます",
+ "imagesLoaded": "{count, plural, =1 {1 枚の画像が読み込まれました} other {#枚の画像が読み込まれました}}",
"Submit": {
"addToCart": "カートに追加",
"outOfStock": "品切れ",
diff --git a/core/messages/nl.json b/core/messages/nl.json
index fc30faaa6..61bca344e 100644
--- a/core/messages/nl.json
+++ b/core/messages/nl.json
@@ -463,8 +463,8 @@
"additionalInformation": "Aanvullende informatie",
"currentStock": "{quantity, number} op voorraad",
"backorderQuantity": "{hoeveelheid, aantal} staat in backorder",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Meer afbeeldingen laden",
+ "imagesLoaded": "{count, plural, =1 {1 afbeelding geladen} other {# afbeeldingen geladen}}",
"Submit": {
"addToCart": "Toevoegen aan winkelmandje",
"outOfStock": "Niet op voorraad",
diff --git a/core/messages/no.json b/core/messages/no.json
index 99b29e946..1197c07cf 100644
--- a/core/messages/no.json
+++ b/core/messages/no.json
@@ -463,8 +463,8 @@
"additionalInformation": "Mer informasjon",
"currentStock": "{antall, nummer} på lager",
"backorderQuantity": "{antall, nummer} vil være restordre",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Laster inn flere bilder",
+ "imagesLoaded": "{antall, flertall, =1 {1 bilde til ble lastet inn} other {# flere bilder ble lastet inn}}",
"Submit": {
"addToCart": "Legg i handlekurv",
"outOfStock": "Utsolgt",
diff --git a/core/messages/sv.json b/core/messages/sv.json
index 539cab066..d16362d17 100644
--- a/core/messages/sv.json
+++ b/core/messages/sv.json
@@ -463,8 +463,8 @@
"additionalInformation": "Ytterligare information",
"currentStock": "{quantity, number} i lager",
"backorderQuantity": "{quantity, number} kommer att vara restnoterade",
- "loadingMoreImages": "Loading more images",
- "imagesLoaded": "{count, plural, =1 {1 more image loaded} other {# more images loaded}}",
+ "loadingMoreImages": "Laddar fler bilder",
+ "imagesLoaded": "{count, plural, =1 {1 till bild har laddats} other {# till bilder har laddats}}",
"Submit": {
"addToCart": "Lägg till i kundvagn",
"outOfStock": "Ej i lager",