Skip to content

Commit

Permalink
Merge pull request #2137 from graphcommerce-org/feature/GCOM-1304-nor…
Browse files Browse the repository at this point in the history
…malize-locale-html-lang

Normalize `<html lang=...` locale (GCOM-1304)
  • Loading branch information
paales authored Jan 15, 2024
2 parents 7e8556e + 6227343 commit 2315ab7
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 15 deletions.
7 changes: 7 additions & 0 deletions .changeset/sixty-zebras-battle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@graphcommerce/magento-product-configurable': patch
'@graphcommerce/lingui-next': patch
'@graphcommerce/next-ui': patch
---

Don't render pseudo-locale in HTML lang attribute
3 changes: 2 additions & 1 deletion examples/magento-graphcms/pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { normalizeLocale } from '@graphcommerce/lingui-next'
import { withLingui } from '@graphcommerce/lingui-next/document/withLingui'
import type { LinguiDocumentProps } from '@graphcommerce/lingui-next/document/withLingui'
import { EmotionCacheProps, withEmotionCache } from '@graphcommerce/next-ui'
Expand All @@ -6,7 +7,7 @@ import NextDocument, { Html, Head, Main, NextScript } from 'next/document'
class Document extends NextDocument<EmotionCacheProps & LinguiDocumentProps> {
render() {
return (
<Html>
<Html lang={normalizeLocale(this.props.locale)}>
<Head>
{/* Inject MUI styles first to match with the prepend: true configuration. */}
<meta name='emotion-insertion-point' content='' />
Expand Down
1 change: 1 addition & 0 deletions packages/lingui-next/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './components/LinguiProvider'
export * from './types'
export * from './lib/normalizeLocale'
24 changes: 24 additions & 0 deletions packages/lingui-next/lib/normalizeLocale.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* To support using multiple storefronts using the same language locale (which
* next.js does not support), we use an additional 'tag' in the locale code in
* which we specify a unique string (i.e. a Magento store code).
*
* This makes next.js happy, as it still follows the BCP47 spec. However, the
* Intl API and other places may not accept this as a valid locale.
*
* Use this method to get a 'normalized' locale that can safely be used in such
* places.
*/
export function normalizeLocale(locale: string | undefined) {
if (!locale) return locale

// Specifically match the xx-yy-storecode format, so we don't accidently 'fix'
// valid locales such as he-Hebr-IL or zh-Hans-CN. This this isn't perfect and
// we should consider a more formalized way to use such pseudo-locales, which
// can be matched more precisely.
const matches = locale?.match(/([a-z]{2})-([a-z]{2})-([a-z]+)/i)
if (matches) {
return `${matches[1]}-${matches[2]}`
}
return locale
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { normalizeLocale } from '@graphcommerce/lingui-next'
import { AddToCartItemSelector, useFormAddProductsToCart } from '@graphcommerce/magento-product'
import { filterNonNullableKeys, ActionCardListProps } from '@graphcommerce/next-ui'
import { i18n } from '@lingui/core'
Expand Down Expand Up @@ -41,10 +42,10 @@ export function ConfigurableProductOptions(props: ConfigurableProductOptionsProp
.length === 0

const allLabels = useMemo(() => {
// Remove optional dialect from locale, which Intl.NumberFormat does not support.
const strippedLocale = locale?.split('-', 2).join('-')

const formatter = new Intl.ListFormat(strippedLocale, { style: 'long', type: 'conjunction' })
const formatter = new Intl.ListFormat(normalizeLocale(locale), {
style: 'long',
type: 'conjunction',
})
return formatter.format(options.map((o) => o.label))
}, [locale, options])

Expand Down
1 change: 1 addition & 0 deletions packages/magento-product-configurable/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@graphcommerce/graphql": "^8.0.0-canary.78",
"@graphcommerce/graphql-mesh": "^8.0.0-canary.78",
"@graphcommerce/image": "^8.0.0-canary.78",
"@graphcommerce/lingui-next": "8.0.0-canary.78",
"@graphcommerce/magento-cart": "^8.0.0-canary.78",
"@graphcommerce/magento-cart-items": "^8.0.0-canary.78",
"@graphcommerce/magento-category": "^8.0.0-canary.78",
Expand Down
8 changes: 3 additions & 5 deletions packages/next-ui/hooks/useDateTimeFormat.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { normalizeLocale } from '@graphcommerce/lingui-next'
import { useRouter } from 'next/router'
import { useMemo } from 'react'

Expand All @@ -6,12 +7,9 @@ export type DateTimeFormatProps = Intl.DateTimeFormatOptions
export function useDateTimeFormat(props?: DateTimeFormatProps) {
const { locale } = useRouter()

// Remove optional dialect from locale, which Intl.NumberFormat does not support.
const strippedLocale = locale?.split('-', 2).join('-')

const formatter = useMemo(
() => new Intl.DateTimeFormat(strippedLocale, props),
[strippedLocale, props],
() => new Intl.DateTimeFormat(normalizeLocale(locale), props),
[locale, props],
)
return formatter
}
8 changes: 3 additions & 5 deletions packages/next-ui/hooks/useNumberFormat.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { normalizeLocale } from '@graphcommerce/lingui-next'
import { useRouter } from 'next/router'
import { useMemo } from 'react'

Expand All @@ -6,12 +7,9 @@ export type NumberFormatProps = Intl.NumberFormatOptions
export function useNumberFormat(props?: NumberFormatProps) {
const { locale } = useRouter()

// Remove optional dialect from locale, which Intl.NumberFormat does not support.
const strippedLocale = locale?.split('-', 2).join('-')

const formatter = useMemo(
() => new Intl.NumberFormat(strippedLocale, props),
[strippedLocale, props],
() => new Intl.NumberFormat(normalizeLocale(locale), props),
[locale, props],
)
return formatter
}
1 change: 1 addition & 0 deletions packages/next-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@graphcommerce/framer-scroller": "^8.0.0-canary.78",
"@graphcommerce/framer-utils": "^8.0.0-canary.78",
"@graphcommerce/image": "^8.0.0-canary.78",
"@graphcommerce/lingui-next": "^8.0.0-canary.78",
"@graphcommerce/prettier-config-pwa": "^8.0.0-canary.78",
"@graphcommerce/typescript-config-pwa": "^8.0.0-canary.78",
"@lingui/core": "^4.2.1",
Expand Down
2 changes: 2 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3967,6 +3967,7 @@ __metadata:
"@graphcommerce/graphql": ^8.0.0-canary.78
"@graphcommerce/graphql-mesh": ^8.0.0-canary.78
"@graphcommerce/image": ^8.0.0-canary.78
"@graphcommerce/lingui-next": 8.0.0-canary.78
"@graphcommerce/magento-cart": ^8.0.0-canary.78
"@graphcommerce/magento-cart-items": ^8.0.0-canary.78
"@graphcommerce/magento-category": ^8.0.0-canary.78
Expand Down Expand Up @@ -4300,6 +4301,7 @@ __metadata:
"@graphcommerce/framer-scroller": ^8.0.0-canary.78
"@graphcommerce/framer-utils": ^8.0.0-canary.78
"@graphcommerce/image": ^8.0.0-canary.78
"@graphcommerce/lingui-next": ^8.0.0-canary.78
"@graphcommerce/prettier-config-pwa": ^8.0.0-canary.78
"@graphcommerce/typescript-config-pwa": ^8.0.0-canary.78
"@lingui/core": ^4.2.1
Expand Down

1 comment on commit 2315ab7

@vercel
Copy link

@vercel vercel bot commented on 2315ab7 Jan 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

graphcommerce-hygraph-dynamic-rows-ui – ./packages/hygraph-dynamic-rows-ui

graphcommerce-hygraph-dynamic-rows-ui-git-canary-graphcommerce.vercel.app
graphcommerce-hygraph-dynamic-rows-ui-graphcommerce.vercel.app
graphcommerce-hygraph-dynamic-rows-ui.vercel.app

Please sign in to comment.