Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const CompareProductsQuery = graphql(`
entityId
name
defaultImage {
url: urlTemplate(lossy: true)
url: urlTemplate
altText
}
path
Expand Down
2 changes: 1 addition & 1 deletion core/app/[locale]/(default)/account/orders/fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const OrderItemFragment = graphql(`
path
}
image {
url: urlTemplate(lossy: true)
url: urlTemplate
altText
}
subTotalListPrice {
Expand Down
2 changes: 1 addition & 1 deletion core/app/[locale]/(default)/blog/[blogId]/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const BlogPageQuery = graphql(`
tags
thumbnailImage {
altText
url: urlTemplate(lossy: true)
url: urlTemplate
}
seo {
pageTitle
Expand Down
2 changes: 1 addition & 1 deletion core/app/[locale]/(default)/blog/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const BlogPostsPageQuery = graphql(
utc
}
thumbnailImage {
url: urlTemplate(lossy: true)
url: urlTemplate
altText
}
}
Expand Down
4 changes: 2 additions & 2 deletions core/app/[locale]/(default)/cart/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const PhysicalItemFragment = graphql(`
brand
sku
image {
url: urlTemplate(lossy: true)
url: urlTemplate
}
entityId
quantity
Expand Down Expand Up @@ -71,7 +71,7 @@ export const DigitalItemFragment = graphql(`
brand
sku
image {
url: urlTemplate(lossy: true)
url: urlTemplate
}
entityId
quantity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const ProductSchemaFragment = graphql(`
numberOfReviews
}
defaultImage {
url: urlTemplate(lossy: true)
url: urlTemplate
}
condition
availabilityV2 {
Expand Down
10 changes: 5 additions & 5 deletions core/app/[locale]/(default)/product/[slug]/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ const MultipleChoiceFieldFragment = graphql(`
... on SwatchOptionValue {
__typename
hexColors
imageUrl(lossy: true, width: 40)
imageUrl(width: 40)
}
... on ProductPickListOptionValue {
__typename
defaultImage {
altText
url: urlTemplate(lossy: true)
url: urlTemplate
}
}
}
Expand Down Expand Up @@ -140,7 +140,7 @@ const ProductPageMetadataQuery = graphql(`
name
defaultImage {
altText
url: urlTemplate(lossy: true)
url: urlTemplate
}
seo {
pageTitle
Expand Down Expand Up @@ -218,14 +218,14 @@ const StreamableProductQuery = graphql(
edges {
node {
altText
url: urlTemplate(lossy: true)
url: urlTemplate
isDefault
}
}
}
defaultImage {
altText
url: urlTemplate(lossy: true)
url: urlTemplate
}
sku
weight {
Expand Down
4 changes: 4 additions & 0 deletions core/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export const client = createClient({
logger:
(process.env.NODE_ENV !== 'production' && process.env.CLIENT_LOGGER !== 'false') ||
process.env.CLIENT_LOGGER === 'true',
imageTransforms: {
enableLossy: true,
lossyQuality: 30,
},
getChannelId: async (defaultChannelId: string) => {
const locale = await getLocale();

Expand Down
2 changes: 1 addition & 1 deletion core/components/footer/fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const FooterFragment = graphql(`
}
... on StoreImageLogo {
image {
url: urlTemplate(lossy: true)
url: urlTemplate
altText
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/components/header/fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const HeaderFragment = graphql(`
}
... on StoreImageLogo {
image {
url: urlTemplate(lossy: true)
url: urlTemplate
altText
}
}
Expand Down
29 changes: 29 additions & 0 deletions core/components/imageWithLqip/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use server';

// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import NextImage, { ImageProps } from 'next/image';

import { buildConfig } from '~/build-config/reader';
import bcCdnImageLoader from '~/lib/cdn-image-loader';

function shouldUseLoaderProp(props: ImageProps): boolean {
if (typeof props.src !== 'string') return false;

const { src } = props;

return buildConfig.get('urls').cdnUrls.some((cdn) => src.startsWith(`https://${cdn}`));
}

/**
* This component should be used in place of Next's `Image` component for images from the
* BigCommerce platform, which will reduce load on the Next.js application for image assets.
*
* It defaults to use the default loader in Next.js if it's an image not from the BigCommerce CDN.
*
* @returns {React.ReactElement} The `<Image>` component
*/
export const Image = ({ ...props }: ImageProps) => {
const loader = shouldUseLoaderProp(props) ? bcCdnImageLoader : undefined;

return <NextImage loader={loader} {...props} />;
};
2 changes: 1 addition & 1 deletion core/components/product-card/fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const ProductCardFragment = graphql(
name
defaultImage {
altText
url: urlTemplate(lossy: true)
url: urlTemplate
}
path
brand {
Expand Down
2 changes: 1 addition & 1 deletion core/components/store-logo/fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const StoreLogoFragment = graphql(`
}
... on StoreImageLogo {
image {
url: urlTemplate(lossy: true)
url: urlTemplate
altText
}
}
Expand Down
4 changes: 4 additions & 0 deletions core/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { writeBuildConfig } from './build-config/writer';
import { client } from './client';
import { graphql } from './client/graphql';
import { cspHeader } from './lib/content-security-policy';
import withPlaiceholder from "@plaiceholder/next";

const withNextIntl = createNextIntlPlugin({
experimental: {
Expand Down Expand Up @@ -113,6 +114,9 @@ export default async (): Promise<NextConfig> => {
// Apply withNextIntl to the config
nextConfig = withNextIntl(nextConfig);

// Apply withPlaiceholder to the config
nextConfig = withPlaiceholder(nextConfig);

if (process.env.ANALYZE === 'true') {
const withBundleAnalyzer = bundleAnalyzer();

Expand Down
2 changes: 2 additions & 0 deletions core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@conform-to/react": "^1.6.1",
"@conform-to/zod": "^1.6.1",
"@icons-pack/react-simple-icons": "^11.2.0",
"@plaiceholder/next": "^3.0.0",
"@radix-ui/react-accordion": "^1.2.11",
"@radix-ui/react-checkbox": "^1.3.2",
"@radix-ui/react-dialog": "^1.1.14",
Expand Down Expand Up @@ -55,6 +56,7 @@
"next-intl": "^4.1.0",
"nuqs": "^2.4.3",
"p-lazy": "^5.0.0",
"plaiceholder": "^3.0.0",
"react": "^19.1.0",
"react-day-picker": "^9.7.0",
"react-dom": "^19.1.0",
Expand Down
Loading
Loading