Skip to content

Commit

Permalink
Fix PDP 404 pages (#71)
Browse files Browse the repository at this point in the history
* Fix PDP 404 pages

* Fix 404.html

* Add feedback
  • Loading branch information
herzog31 authored Jul 12, 2024
1 parent fe8d9c9 commit 314ae68
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 43 deletions.
8 changes: 8 additions & 0 deletions 404.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@

<head>
<title>Page not found</title>
<script type="importmap">
{
"imports": {
"@dropins/tools/": "/scripts/__dropins__/tools/",
"@dropins/storefront-pdp/": "/scripts/__dropins__/storefront-pdp/"
}
}
</script>
<script type="text/javascript">
window.isErrorPage = true;
window.errorCode = '404';
Expand Down
42 changes: 16 additions & 26 deletions blocks/product-details-custom/product-details-custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,12 @@ import {
performCatalogServiceQuery,
refineProductQuery,
setJsonLd,
loadErrorPage,
} from '../../scripts/commerce.js';
import { readBlockConfig } from '../../scripts/aem.js';

const html = htm.bind(h);

export function errorGettingProduct(code = 404) {
fetch(`/${code}.html`).then((response) => {
if (response.ok) {
return response.text();
}
throw new Error(`Error getting ${code} page`);
}).then((htmlText) => {
const parser = new DOMParser();
const doc = parser.parseFromString(htmlText, 'text/html');
document.body.innerHTML = doc.body.innerHTML;
document.head.innerHTML = doc.head.innerHTML;
});
document.body.innerHTML = '';
}

async function getVariantDetails(variantIds, sku) {
const result = await performCatalogServiceQuery(
refineProductQuery,
Expand Down Expand Up @@ -101,15 +87,17 @@ class ProductDetailPage extends Component {
if (!product) {
throw new Error("Couldn't get product");
}

this.setState({
product,
loading: false,
selection: {},
});
} catch (e) {
errorGettingProduct();
await loadErrorPage();
} finally {
this.props.resolve();
}

this.setState({
product,
loading: false,
selection: {},
});
}

onAddToCart = async () => {
Expand Down Expand Up @@ -200,10 +188,12 @@ export default async function decorate($block) {

const skuFromUrl = getSkuFromUrl() || blockConfig.sku;
if (!skuFromUrl) {
errorGettingProduct();
await loadErrorPage();
return Promise.reject();
}

const app = html`<${ProductDetailPage} sku=${skuFromUrl} />`;

render(app, $block);
return new Promise((resolve) => {
const app = html`<${ProductDetailPage} sku=${skuFromUrl} resolve=${resolve} />`;
render(app, $block);
});
}
25 changes: 8 additions & 17 deletions blocks/product-details/product-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,15 @@ import { render as productRenderer } from '@dropins/storefront-pdp/render.js';
import ProductDetails from '@dropins/storefront-pdp/containers/ProductDetails.js';

// Libs
import { getProduct, getSkuFromUrl, setJsonLd } from '../../scripts/commerce.js';
import {
getProduct,
getSkuFromUrl,
setJsonLd,
loadErrorPage,
} from '../../scripts/commerce.js';
import { getConfigValue } from '../../scripts/configs.js';
import { fetchPlaceholders } from '../../scripts/aem.js';

// Error Handling (404)
async function errorGettingProduct(code = 404) {
const htmlText = await fetch(`/${code}.html`).then((response) => {
if (response.ok) {
return response.text();
}
throw new Error(`Error getting ${code} page`);
});
const parser = new DOMParser();
const doc = parser.parseFromString(htmlText, 'text/html');
document.body.innerHTML = doc.body.innerHTML;
document.head.innerHTML = doc.head.innerHTML;
}

async function addToCart({
sku, quantity, optionsUIDs, product,
}) {
Expand Down Expand Up @@ -123,7 +114,7 @@ export default async function decorate(block) {
window.getProductPromise, fetchPlaceholders()]);

if (!product) {
await errorGettingProduct();
await loadErrorPage();
return Promise.reject();
}

Expand Down Expand Up @@ -273,7 +264,7 @@ export default async function decorate(block) {
})(block);
} catch (e) {
console.error(e);

Check warning on line 266 in blocks/product-details/product-details.js

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
await errorGettingProduct();
await loadErrorPage();
} finally {
resolve();
}
Expand Down
30 changes: 30 additions & 0 deletions scripts/commerce.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,33 @@ export function setJsonLd(data, name) {
script.dataset.name = name;
document.head.appendChild(script);
}

export async function loadErrorPage(code = 404) {
const htmlText = await fetch(`/${code}.html`).then((response) => {
if (response.ok) {
return response.text();
}
throw new Error(`Error getting ${code} page`);
});
const parser = new DOMParser();
const doc = parser.parseFromString(htmlText, 'text/html');
document.body.innerHTML = doc.body.innerHTML;
document.head.innerHTML = doc.head.innerHTML;

// When moving script tags via innerHTML, they are not executed. They need to be re-created.
const notImportMap = (c) => c.textContent && c.type !== 'importmap';
Array.from(document.head.querySelectorAll('script'))
.filter(notImportMap)
.forEach((c) => c.remove());
Array.from(doc.head.querySelectorAll('script'))
.filter(notImportMap)
.forEach((oldScript) => {
const newScript = document.createElement('script');
Array.from(oldScript.attributes).forEach(({ name, value }) => {
newScript.setAttribute(name, value);
});
const scriptText = document.createTextNode(oldScript.innerHTML);
newScript.appendChild(scriptText);
document.head.appendChild(newScript);
});
}

0 comments on commit 314ae68

Please sign in to comment.