Components/BlogList/Default.liquid.{
"totalPages": 1,
"page": 1,
"categories": [
{
"id": "Category Id",
"title": "Sample category title",
"alias": "sample-category-alias"
},
...
],
"generalImage": null,
"blogList": [
{
"title": "Sample blog title",
"content": "<p>Sample content</p>",
"summaryHtml": "<p>Sample summary</p>",
"alias": "sample-blog-alias",
"publishedAt": "2025-01-01T00:00:00+00:00",
"mediaItem": {
"id": "Image Id",
"link": "https://example.com/sample",
"mediaType": "Image"
}
},
...
],
"name": "BlogList",
"view": "Default",
"section": "SectionA",
"settings": {
"id": "Component Id",
"section": "SectionA",
"type": "NoirBlogList",
"name": "BlogList",
"configuredInContentApi": true,
"view": "Default",
"displayName": "",
"cssClass": ""
},
"translations": {
"stayInformed": "Sample translation",
"previousPage": "Sample translation",
"nextPage": "Sample translation",
"...": "..."
}
}settings.idcomp-{{ id }}pagination.pageNumber (number)pagination.numberOfPages (number)settings.cssClass(UNDEFINED).Root.Page.Data (page-level view model).categories[]generalImage (object or null)blogList[]x-data='bloglistdefault.singlePost({{ blog.content | serialize }})'@click="bloglistdefault.redirectToState(pageNumber)"time: { hours: -1, minutes: -1 }init()getReadingTime()time.hours = -1 means “don’t show hours”.time.minutes:-1 → not computed-2 → “< 1 minute”>= 1 → minutesthis.getReadingTime().content using an assumed speed of 3.8 words/sec and stores it in this.time.hours > 0, sets this.time.hours.minutes === 0 and seconds > 0, sets this.time.minutes = -2.minutes > 0, sets this.time.minutes (rounded up when seconds remain).newPage is a stringwindow.location.href = newPagenewPage is a numberpage:const params = new URLSearchParams();params.set("page", Number(newPage));${window.location.pathname}?page=<n>newPage is null/undefinedwindow.location.href = window.location.pathname + window.location.searchx-data, x-show, reactive time fields)blog.content is used for reading time calculation. If it contains HTML, the word count will include markup tokens as words, which can slightly affect the reading time estimate.?page= URL.Root.Page.Data.BlogCategory; if the page data doesn’t set it consistently, the active link highlighting/description/image may not behave as expected.translations.stayInformedcurrentCategory = Root.Page.Data.BlogCategory.currentCategory.description exists, it is rendered under the title.currentCategory.mediaItem.link exists)generalImage.link (if provided)translations.noImageAltAvailable when needed./blog/posts/blog/posts/<alias>pointer-events-none + secondary text class./blog/post/<blog.alias>mediaItem.link, it shows an image.summaryHtml exists, it renders that.content.x-data='singlePost({{ blog.content | serialize }})'< 1 minute when minutes are effectively below 1