create-brainerce-store 1.52.4 → 1.52.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/templates/nextjs/base/next.config.ts +11 -1
- package/templates/nextjs/base/src/app/layout.tsx.ejs +7 -3
- package/templates/nextjs/base/src/core/providers/store-provider.tsx.ejs +10 -1
- package/templates/nextjs/designs/atelier/app-overlay/layout.tsx.ejs +7 -3
- package/templates/nextjs/designs/atelier/ui/shared/icons.tsx +1 -1
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var require_package = __commonJS({
|
|
|
31
31
|
"package.json"(exports2, module2) {
|
|
32
32
|
module2.exports = {
|
|
33
33
|
name: "create-brainerce-store",
|
|
34
|
-
version: "1.52.
|
|
34
|
+
version: "1.52.5",
|
|
35
35
|
description: "Scaffold a production-ready e-commerce storefront connected to Brainerce",
|
|
36
36
|
bin: {
|
|
37
37
|
"create-brainerce-store": "dist/index.js"
|
package/package.json
CHANGED
|
@@ -26,7 +26,17 @@ const nextConfig: NextConfig = {
|
|
|
26
26
|
// isomorphic-dompurify ships jsdom, which at runtime reads stylesheet files
|
|
27
27
|
// from its own package directory. Webpack bundling breaks those relative
|
|
28
28
|
// lookups — loading it externally from node_modules keeps the paths intact.
|
|
29
|
-
|
|
29
|
+
//
|
|
30
|
+
// brainerce (the SDK) is imported across both the server and client
|
|
31
|
+
// compilation boundaries in ~60 files, including the [locale]/layout.tsx
|
|
32
|
+
// route (see generateStaticParams below) whose static params are resolved
|
|
33
|
+
// by a separate jest-worker child process in `next dev` (webpack). That
|
|
34
|
+
// worker requires the compiled page against the vendor-chunks manifest
|
|
35
|
+
// while the main dev server may still be writing it, which can throw
|
|
36
|
+
// "Cannot find module './vendor-chunks/brainerce.js'". Excluding it from
|
|
37
|
+
// server bundling (loaded externally from node_modules instead) avoids the
|
|
38
|
+
// race.
|
|
39
|
+
serverExternalPackages: ['isomorphic-dompurify', 'brainerce'],
|
|
30
40
|
images: {
|
|
31
41
|
// The storefront is a consumer of the Brainerce API — it has to render
|
|
32
42
|
// whatever image URLs the API returns. In practice those URLs are
|
|
@@ -7,7 +7,7 @@ import { SiteHeader } from '@/ui/layout/site-header';
|
|
|
7
7
|
import { SiteFooter } from '@/ui/layout/site-footer';
|
|
8
8
|
import { BrainerceBotWidget } from '@/components/brainerce-bot';
|
|
9
9
|
import { getServerClient, fetchStoreInfo } from '@/core/lib/brainerce';
|
|
10
|
-
import { getDirection, supportedLocales } from '@/i18n';
|
|
10
|
+
import { getDirection, getMessages, supportedLocales } from '@/i18n';
|
|
11
11
|
import { getNonce } from '@/core/lib/nonce';
|
|
12
12
|
import '../globals.css';
|
|
13
13
|
|
|
@@ -62,7 +62,7 @@ export default async function RootLayout({
|
|
|
62
62
|
// seeded a particular content type yet. New stores ship with default rows
|
|
63
63
|
// seeded by the backend (StoresService.seedDefaultContent).
|
|
64
64
|
const client = getServerClient(locale);
|
|
65
|
-
const [announcements, siteHeader, siteFooter, storeInfo] = await Promise.all([
|
|
65
|
+
const [announcements, siteHeader, siteFooter, storeInfo, messages] = await Promise.all([
|
|
66
66
|
client.content.announcement.list(locale).catch(() => []),
|
|
67
67
|
client.content.header.get('main', locale).catch(() => null),
|
|
68
68
|
client.content.footer.get('main', locale).catch(() => null),
|
|
@@ -70,6 +70,10 @@ export default async function RootLayout({
|
|
|
70
70
|
// render with the real currency, feature flags, and i18n config at frame 0
|
|
71
71
|
// — without this, Googlebot sees USD/defaults baked into the HTML.
|
|
72
72
|
fetchStoreInfo(locale),
|
|
73
|
+
// SSR-fetch UI message strings so translated text renders at frame 0 —
|
|
74
|
+
// without this, every page (and every locale switch) shows raw
|
|
75
|
+
// "namespace.key" strings until the client-only fetch resolves.
|
|
76
|
+
getMessages(locale),
|
|
73
77
|
]);
|
|
74
78
|
|
|
75
79
|
return (
|
|
@@ -100,7 +104,7 @@ export default async function RootLayout({
|
|
|
100
104
|
/>
|
|
101
105
|
</head>
|
|
102
106
|
<body className={font.className}>
|
|
103
|
-
<StoreProvider locale={locale} initialStoreInfo={storeInfo}>
|
|
107
|
+
<StoreProvider locale={locale} initialStoreInfo={storeInfo} initialMessages={messages}>
|
|
104
108
|
<div className="min-h-screen flex flex-col">
|
|
105
109
|
<AnnouncementBar announcements={announcements} />
|
|
106
110
|
<SiteHeader header={siteHeader} storeName={<%- storeNameJs %>} />
|
|
@@ -74,10 +74,12 @@ export function StoreProvider({
|
|
|
74
74
|
children,
|
|
75
75
|
locale,
|
|
76
76
|
initialStoreInfo = null,
|
|
77
|
+
initialMessages,
|
|
77
78
|
}: {
|
|
78
79
|
children: React.ReactNode;
|
|
79
80
|
locale?: string;
|
|
80
81
|
initialStoreInfo?: PublicStoreInfo | null;
|
|
82
|
+
initialMessages?: Record<string, Record<string, string>>;
|
|
81
83
|
}) {
|
|
82
84
|
<% } else { %>
|
|
83
85
|
export function StoreProvider({
|
|
@@ -99,7 +101,14 @@ export function StoreProvider({
|
|
|
99
101
|
const [cart, setCart] = useState<Cart | null>(null);
|
|
100
102
|
const [cartLoading, setCartLoading] = useState(true);
|
|
101
103
|
<% if (i18nEnabled) { %>
|
|
102
|
-
|
|
104
|
+
// Seed from server-rendered messages (see RootLayout) so translated text
|
|
105
|
+
// renders at frame 0 instead of a window of raw "namespace.key" strings
|
|
106
|
+
// before the client-only fetch in the effect below resolves — this also
|
|
107
|
+
// closes the same gap on every locale switch, since RootLayout re-runs
|
|
108
|
+
// server-side per locale and StoreProvider remounts with fresh initial data.
|
|
109
|
+
const [messages, setMessages] = useState<Record<string, Record<string, string>>>(
|
|
110
|
+
initialMessages ?? {}
|
|
111
|
+
);
|
|
103
112
|
<% } %>
|
|
104
113
|
|
|
105
114
|
// Check auth status via httpOnly cookie (server-side validation)
|
|
@@ -8,7 +8,7 @@ import { SiteFooter } from '@/ui/layout/site-footer';
|
|
|
8
8
|
import { CartDrawer } from '@/ui/cart/cart-drawer';
|
|
9
9
|
import { BrainerceBotWidget } from '@/components/brainerce-bot';
|
|
10
10
|
import { getServerClient, fetchStoreInfo } from '@/core/lib/brainerce';
|
|
11
|
-
import { getDirection, supportedLocales } from '@/i18n';
|
|
11
|
+
import { getDirection, getMessages, supportedLocales } from '@/i18n';
|
|
12
12
|
import { getNonce } from '@/core/lib/nonce';
|
|
13
13
|
import '../globals.css';
|
|
14
14
|
|
|
@@ -75,7 +75,7 @@ export default async function RootLayout({
|
|
|
75
75
|
// seeded a particular content type yet. New stores ship with default rows
|
|
76
76
|
// seeded by the backend (StoresService.seedDefaultContent).
|
|
77
77
|
const client = getServerClient(locale);
|
|
78
|
-
const [announcements, siteHeader, siteFooter, storeInfo] = await Promise.all([
|
|
78
|
+
const [announcements, siteHeader, siteFooter, storeInfo, messages] = await Promise.all([
|
|
79
79
|
client.content.announcement.list(locale).catch(() => []),
|
|
80
80
|
client.content.header.get('main', locale).catch(() => null),
|
|
81
81
|
client.content.footer.get('main', locale).catch(() => null),
|
|
@@ -83,6 +83,10 @@ export default async function RootLayout({
|
|
|
83
83
|
// render with the real currency, feature flags, and i18n config at frame 0
|
|
84
84
|
// — without this, Googlebot sees USD/defaults baked into the HTML.
|
|
85
85
|
fetchStoreInfo(locale),
|
|
86
|
+
// SSR-fetch UI message strings so translated text renders at frame 0 —
|
|
87
|
+
// without this, every page (and every locale switch) shows raw
|
|
88
|
+
// "namespace.key" strings until the client-only fetch resolves.
|
|
89
|
+
getMessages(locale),
|
|
86
90
|
]);
|
|
87
91
|
|
|
88
92
|
return (
|
|
@@ -113,7 +117,7 @@ export default async function RootLayout({
|
|
|
113
117
|
/>
|
|
114
118
|
</head>
|
|
115
119
|
<body className={`${sans.variable} ${serif.variable} font-sans`}>
|
|
116
|
-
<StoreProvider locale={locale} initialStoreInfo={storeInfo}>
|
|
120
|
+
<StoreProvider locale={locale} initialStoreInfo={storeInfo} initialMessages={messages}>
|
|
117
121
|
<div className="min-h-screen flex flex-col">
|
|
118
122
|
<AnnouncementBar announcements={announcements} />
|
|
119
123
|
<SiteHeader header={siteHeader} storeName={<%- storeNameJs %>} />
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import * as React from 'react';
|
|
8
8
|
|
|
9
9
|
export type IconProps = {
|
|
10
|
-
size?: 16 | 18 | 20 | 24 | 28 | 32;
|
|
10
|
+
size?: 16 | 18 | 20 | 24 | 28 | 32 | 56;
|
|
11
11
|
className?: string;
|
|
12
12
|
/** stroke width — 1.75 default matches the light, jewelry-grade look */
|
|
13
13
|
strokeWidth?: number;
|