PEN BEAM / COPY-READY EXAMPLE
Fetch Data with a Timeout and Error State
Request an endpoint with a timeout and explicit HTTP/network error handling using vanilla JavaScript.
What this snippet does
Requests data with a timeout, checks the HTTP status and separates network failures from application-level errors.
JavaScript / source code
async function fetchJson(url, timeoutMs = 8000) {
const controller = new AbortController();
const timeoutId = window.setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, {
method: 'GET',
headers: { Accept: 'application/json' },
signal: controller.signal,
credentials: 'same-origin'
});
if (!response.ok) {
throw new Error(`Request failed with HTTP ${response.status}`);
}
return await response.json();
} finally {
window.clearTimeout(timeoutId);
}
}
const statusElement = document.querySelector('[data-fetch-status]');
const listElement = document.querySelector('[data-fetch-list]');
function showStatus(message) {
if (statusElement) statusElement.textContent = message;
}
function renderItems(items) {
if (!listElement || !Array.isArray(items)) return;
listElement.replaceChildren();
items.forEach((item) => {
const row = document.createElement('li');
const renderedTitle = item && item.title && typeof item.title.rendered === 'string'
? item.title.rendered
: (item && typeof item.title === 'string' ? item.title : 'Untitled item');
// Convert encoded title markup to text; never inject API strings as HTML.
row.textContent = new DOMParser().parseFromString(renderedTitle, 'text/html').body.textContent || 'Untitled item';
listElement.appendChild(row);
});
}
fetchJson('/wp-json/wp/v2/posts?per_page=5')
.then((items) => {
renderItems(items);
showStatus('Content loaded.');
})
.catch((error) => {
showStatus(error.name === 'AbortError'
? 'The request timed out. Please retry.'
: 'The request could not be completed. Please retry.');
});Where to place it
Add the required markup (an element with data-fetch-status and a list with data-fetch-list), then place this JavaScript in an enqueued theme script. Replace the endpoint and item-field mapping to match your application.
Back up the relevant file or settings first. Apply the change on staging, verify behavior, and retain a rollback path before production deployment.
What to check before deploying
- Confirm the target endpoint is public or uses an authenticated server-side route; never expose API keys in browser code.
- Test the timeout, non-2xx response and malformed JSON paths, and confirm the UI reports useful errors.
- Check that returned text is inserted with textContent rather than injected as HTML; test mobile and keyboard use.