Content Card is a generic card-component that can be extended into a variety of card types, such as articles, products, videos, and more. It can output structured markup for SEO and rich snippets. It consists of two areas: Media Area and Content Area.
This area contains visual elements like images or videos.
src
, srcset
for different resolutions, alt
text, width
, height
, decode
and loading
attributes.src
, poster
image, tracks
for subtitles/captions, and player options
(like autoplay, controls, loop, muted).figcaption
to describe the media.This area contains the main information of the card, including text, metadata, and actions.
h2
, h3
) can be specified with the headlineTag
property in the content
object. Defaults to h2
.summary
and a more detailed text
field, which can contain simple HTML.published
date/time (can be formatted as absolute, relative, or a full string).modified
date/time.readingTime
.reactions
(e.g., Likes, Dislikes, with icon
, count
, and active
state).commentCount
.shareCount
.viewCount
.name
, role
, and a clickable avatar
image.contacts
(e.g., email, Twitter) which are rendered as links.url
to their profile.url
) with a name
.current
price.original
price (for showing discounts).currency
.discountText
(e.g., âSave 28%â).count
of ratings.primary
and secondary
groups.link
or a button
.text
, a url
(for links), an icon
, and an ariaLabel
.isWrapper: true
.popover: true
.A generic popover can be attached to any card type.
popover
object to the root of the cardâs data."popover": true
will open it.popover
object has a type
which determines its content.
type: "video"
: Expects a video
object with src
and options
.type: "article"
: Expects a content
string, which can be HTML.Here are the card types supported by the component, with examples in data.json
. Each card type can optionally include Schema.org structured data markup when useSchema: true
(default setting).
A standard card for blog posts, news, or articles.
Article
(optional)Image
is typical.Category/Tagline
, Headline
, optional Subheadline
, and Summary/Text
.Publication Info
(especially published
date and readingTime
), and Engagement Counts
.Authors
and Tags
.Designed to showcase a product for e-commerce.
Product
(optional)Image
or a short Video
.Ribbon
or Sticker
to highlight sales or new items (e.g., â20% OFFâ).Category/Tagline
for the product category, Headline
for the product name.Price
, Availability
, and Rating
are key components.A card focused on presenting a video.
VideoObject
(optional)Video
or YouTube
embed, usually with a poster
image to attract clicks.Headline
for the video title, and Summary/Text
for a brief description.Publication Info
(upload date) and Engagement Counts
(especially viewCount
).A simple card to feature a person.
Person
(optional)Image
for the authorâs avatar/profile picture.Authors
section would be the main content, showing name
, role
, and contacts
.Used to announce and provide details about an event.
Event
or specific event types like BusinessEvent
(optional)Image
.Headline
for the event title, summary
for the description, and published
for the date.popover
with more details.An interactive card to engage users with a question.
Question
(optional)Headline
for the poll question.viewCount
can show how many people have participated.A simple, visual card for displaying quotes.
Quotation
(optional)Image
.summary
for the quote itself.Authors
section to attribute the quote.Similar to Article Card but specifically for news content with NewsArticle schema.
NewsArticle
(optional)Image
is typical, often with news-specific overlays like âLIVEâ ribbons.Ribbon
for breaking news or live events, Sticker
for âNewâ or âUpdatedâ status.Category
(e.g., âWorld Newsâ, âTechnologyâ), Headline
, optional Subheadline
, and Summary
.Publication Info
with both published
and modified
dates, readingTime
, and engagement metrics.Authors
(journalists/reporters) and news-specific Tags
.A specialized card for food recipes with Recipe schema.
Recipe
(optional)Image
.Ribbon
for âPopularâ, âFeaturedâ, or dietary badges like âVegetarianâ.Category
(cuisine type), Headline
(recipe name), and Summary
(brief description).prepTime
: Preparation time.cookTime
: Cooking time.servings
: Number of servings.instructions
: Step-by-step cooking instructions.text
field as an array.readingTime
(total time), star ratings, and engagement counts.Authors
(chefs/recipe creators).Designed for events, conferences, and gatherings with Event schema.
Event
or specific subtypes like BusinessEvent
(optional)Image
.Category
(e.g., âBusinessEventâ, âConferenceâ), Headline
(event name), and Summary
.startDate
and endDate
: Event timing.location
: Venue name and address.organizer
: Event organizer information.offers
: Ticket pricing information.status
: Event status (Scheduled, Cancelled, etc.).attendanceMode
: Online, offline, or mixed.A professional card for local businesses with LocalBusiness schema.
LocalBusiness
(optional)Image
.Headline
(business name) and Summary
(business description).address
: Complete business address with street, city, region, postal code.geo
: Latitude and longitude coordinates.mapProvider
: Configuration for embedded maps (OpenStreetMap, Google Maps, etc.).telephone
and email
: Contact information.website
: Business website URL.sameAs
: Social media profiles array.foundingDate
: When the business was established.openingHours
: Business hours with both schema and display formats.An interactive card for user polls and surveys.
Question
(optional)Category
(âCommunity Pollâ), Headline
(poll question), and Summary
.text
field with id
, headline
, and description.endpoint
: API endpoint for vote submission.allowMultiple
: Whether multiple selections are allowed.showResults
: When to show results (âafterVoteâ, âalwaysâ, etc.).totalVotes
: Current vote count.labels
: Customizable text labels for the interface.viewCount
showing poll participation.A card for frequently asked questions with FAQPage schema.
FAQPage
(optional)Headline
(âFrequently Asked Questionsâ) and optional category.text
field.
headline
(question) and text
(answer).A card for displaying chronological events with EventSeries schema.
EventSeries
(optional)Category
(e.g., âHistoryâ), Headline
(timeline title).text
field.
headline
(time period/date) and text
(event description).startDate
, endDate
, and location
for enhanced schema markup.All card types support optional Schema.org structured data markup, which enhances SEO and enables rich snippets in search results. Schema markup is enabled by default (useSchema: true
) but can be disabled per card or globally.
// Disable for a specific card
const cardSettings = { useSchema: false };
card.dataset = { data: cardData, settings: cardSettings };
// Disable via HTML attribute
<article-card settings='{"useSchema": false}'></article-card>
headline
: Main titlearticleSection
: CategorydatePublished
: Publication datedateModified
: Last update datedescription
: Summary textarticleBody
: Full contentauthor
: Author informationname
: Recipe titledescription
: Recipe summaryrecipeCategory
: Cuisine typeprepTime
: Preparation timecookTime
: Cooking timerecipeYield
: Number of servingsrecipeIngredient
: List of ingredientsrecipeInstructions
: Cooking stepsname
: Event namedescription
: Event descriptionstartDate
: Event start timeendDate
: Event end timelocation
: Venue informationorganizer
: Event organizereventStatus
: Event statuseventAttendanceMode
: Attendance typename
: Business namedescription
: Business descriptionaddress
: Full address detailsgeo
: Geographic coordinatestelephone
: Phone numberemail
: Email addressopeningHours
: Business hourssameAs
: Social media profilesname
: Product namedescription
: Product descriptionsku
: Product identifiercategory
: Product categoryoffers
: Pricing informationaggregateRating
: Customer ratingsThe BaseCard
class serves as the foundation for all card types, providing:
useSchema: true
(default).settings
attribute.render()
method for subclass implementation.<article-card>
, <recipe-card>
).dataset
property or by setting data
directly.// Setting data programmatically
const articleCard = document.createElement('article-card');
articleCard.dataset = {
data: articleData,
settings: {
useSchema: true,
styles: { 'cc-headline': 'class="custom-headline"' }
}
};
// Using settings attribute
<recipe-card settings='{"useSchema": false}'></recipe-card>
// Accessing card properties
const settings = articleCard.settings;
const data = articleCard.data;
All card types share a common data structure with the following top-level properties:
{
"id": "unique-identifier", // Unique card identifier
"type": "article|news|recipe|...", // Card type for component selection
"media": { ... }, // Media configuration (optional)
"ribbon": { ... }, // Ribbon overlay (optional)
"sticker": { ... }, // Sticker/badge overlay (optional)
"content": { ... }, // Core content data
"authors": [...], // Author information (optional)
"engagement": { ... }, // Engagement metrics (optional)
"tags": [...], // Tag/category links (optional)
"links": [...], // Navigation links (optional)
"actions": [...], // Action buttons (optional)
// Type-specific properties (recipe, event, business, poll, etc.)
}
"media": {
"sources": [
{
"type": "image|video",
"src": "path/to/media",
"alt": "Description",
"srcset": "responsive-sizes", // Optional
"width": 800, // Optional
"height": 600, // Optional
"loading": "lazy|eager", // Optional
"poster": "path/to/poster" // For videos
}
],
"caption": "Media description" // Optional figcaption
}
// Ribbon - larger banner overlay
"ribbon": {
"text": "FEATURED",
"style": "featured|live|popular",
"color": "#ff0000" // Optional custom color
}
// Sticker - smaller badge overlay
"sticker": {
"text": "NEW",
"style": "badge|pill",
"position": "top-left|top-right|bottom-left|bottom-right"
}
"content": {
"category": "Category Name", // Content categorization
"headline": "Main Title", // Primary heading
"headlineTag": "h2", // HTML heading level (default: h2)
"subheadline": "Secondary Title", // Optional subtitle
"summary": "Brief description", // Short description text
"text": "Detailed content", // Full content (can be HTML or array)
"published": {
"datetime": "2025-07-16T10:00:00Z",
"formatted": "July 16, 2025"
},
"modified": { // Optional update information
"datetime": "2025-07-16T12:00:00Z",
"formatted": "(Updated July 16, 2025)"
},
"readingTime": "5 min read" // Time estimate
}
"authors": [
{
"name": "John Doe",
"role": "Senior Developer", // Optional job title/role
"avatar": "path/to/avatar.jpg", // Optional profile image
"url": "https://johndoe.com", // Optional profile link
"contacts": [ // Optional contact methods
{
"type": "email|twitter|linkedin",
"url": "mailto:john@example.com",
"label": "Email John"
}
]
}
]
"engagement": {
"reactions": [
{
"type": "like|dislike|love",
"icon": "thumbs_up",
"count": 150,
"value": 4.5, // For ratings (optional)
"max": 5, // Maximum rating value (optional)
"min": 0, // Minimum rating value (optional)
"active": false, // User's current state (optional)
"ariaLabel": "Like this post"
}
],
"commentCount": 25,
"shareCount": 80,
"viewCount": 1500
}
"links": [
{
"url": "https://example.com",
"text": "Read More",
"icon": "external-link", // Optional icon
"hideText": false, // Show/hide text (default: false)
"isWrapper": false // Make entire card clickable (default: false)
}
]
"actions": [
{
"text": "Save Article",
"icon": "bookmark", // Optional icon
"url": "https://save.com", // For link actions
"ariaLabel": "Save this article", // Accessibility label
"popover": { // For popover actions
"content": "<h3>Saved!</h3><p>Article saved to your reading list.</p>"
},
"attributes": { // Additional HTML attributes
"type": "submit",
"data-action": "save"
}
}
]
"recipe": {
"prepTime": "PT15M", // ISO 8601 duration or readable format
"cookTime": "PT30M",
"servings": "4",
"instructions": [ // Step-by-step instructions
"Preheat oven to 350°F",
"Mix ingredients in a bowl",
"Bake for 30 minutes"
]
}
"event": {
"startDate": "2025-10-25T09:00:00",
"endDate": "2025-10-26T17:00:00",
"location": {
"name": "Convention Center",
"address": "123 Main St, City, State 12345"
},
"organizer": {
"name": "Event Organization"
},
"offers": [
{
"name": "Early Bird",
"price": "299",
"currency": "USD"
}
],
"status": "Scheduled", // EventStatus
"attendanceMode": "OfflineEventAttendanceMode"
}
"business": {
"address": {
"streetAddress": "123 Main Street",
"addressLocality": "San Francisco",
"addressRegion": "CA",
"postalCode": "94105",
"addressCountry": "US"
},
"geo": {
"latitude": "37.7749",
"longitude": "-122.4194",
"mapProvider": {
"type": "openstreetmap",
"name": "OpenStreetMap",
"url": "https://www.openstreetmap.org/export/embed.html?bbox={lng1},{lat1},{lng2},{lat2}",
"latOffset": 0.003,
"lngOffset": 0.005,
"zoom": 15
}
},
"telephone": "+1-415-555-0123",
"email": "hello@business.com",
"website": "https://business.com",
"sameAs": [ // Social media profiles
"https://facebook.com/business",
"https://twitter.com/business"
],
"foundingDate": "2018-03-15",
"openingHours": [
{
"schema": "Mo-Fr 06:00-20:00", // Schema.org format
"display": "Monday - Friday: 6:00 AM - 8:00 PM"
}
]
}
"poll": {
"endpoint": "./api/polls/poll-1.json",
"allowMultiple": false, // Allow multiple selections
"showResults": "afterVote", // When to show results
"totalVotes": 5420,
"labels": { // Customizable UI labels
"vote": "Vote",
"submitVote": "Submit Vote",
"results": "Results",
"totalVotes": "Total votes:",
"votes": "votes"
}
}
Below is the proposed semantic HTML markup for each component part.
<figure class="ic-media">
<!-- Image -->
<img
class="ic-media-image"
src="..."
srcset="..."
alt="..."
width="..."
height="..."
loading="lazy"
>
<!-- Video -->
<video
class="ic-media-video"
src="..."
poster="..."
controls
autoplay
muted
loop
>
<track kind="captions" src="..." srclang="en" label="English">
</video>
<!--
Overlays
Using role="status" helps assistive technologies identify these as status indicators.
-->
<div class="ic-ribbon" role="status">FEATURED</div>
<span class="ic-sticker" role="status">NEW</span>
<!-- Caption -->
<figcaption class="ic-media-caption">This is a caption.</figcaption>
</figure>
Note on Gallery Usage: The <figure>
element is flexible and can contain multiple images or videos to create a small gallery. The figcaption
would then describe the entire gallery.
<figure class="ic-media">
<img class="ic-media-image" src="gallery-1.jpg" alt="...">
<img class="ic-media-image" src="gallery-2.jpg" alt="...">
<figcaption class="ic-media-caption">A gallery of items.</figcaption>
</figure>
<article class="ic-content">
<!-- Core Content -->
<strong class="ic-category">Technology</strong>
<!-- The heading tag below is dynamic (h2, h3, etc.) based on content.headlineTag -->
<h2 class="ic-headline">Card Headline</h2>
<h3 class="ic-subheadline">Card Subheadline</h3>
<p class="ic-summary">A brief summary of the content.</p>
<div class="ic-text">
<p>More detailed text can go here, including <strong>HTML</strong> elements.</p>
</div>
<!-- Metadata & Engagement -->
<div class="ic-meta">
<time class="ic-published" datetime="2023-10-01T12:00:00Z">October 1, 2023</time>
<span class="ic-reading-time">5 min read</span>
</div>
<div class="ic-engagement">
<button class="ic-reaction" aria-pressed="false">
<span class="ic-reaction-icon">đ</span> 100
</button>
<span class="ic-comments">25 comments</span>
<span class="ic-views">1.5k views</span>
</div>
<!--
Attribution & Grouping
The <address> tag is used here because it semantically represents the contact information
for the author(s) of the parent <article> element.
-->
<address class="ic-authors">
<div class="ic-author">
<a href="/authors/john-doe" class="ic-author-link">
<img class="ic-avatar" src="..." alt="John Doe" width="40" height="40">
<span class="ic-author-name">John Doe</span>
</a>
<span class="ic-author-role">Author</span>
</div>
<!-- Repeat .ic-author div for multiple authors -->
</address>
<ul class="ic-tags">
<li><a href="/tags/tech" class="ic-tag">Technology</a></li>
</ul>
<!-- Product Information -->
<section class="ic-product">
<h4 class="ic-product-name">Premium Course</h4>
<div class="ic-product-price">
<span>USD 49.99</span>
<del class="ic-product-price-original">USD 69.99</del>
<span class="ic-product-discount">Save 28%</span>
</div>
<div class="ic-product-rating" role="img" aria-label="Rating: 4.7 out of 5 stars">
<span aria-hidden="true">â
â
â
â
â</span>
<span>(4.7/5 from 356 ratings)</span>
</div>
<span class="ic-product-availability">In Stock</span>
</section>
<!-- Actions -->
<div class="ic-actions">
<a href="..." class="ic-action-primary">
<span class="ic-action-icon">â¶</span> Read more
</a>
<button type="button" class="ic-action-secondary">
<span class="ic-action-icon">...</span> Save
</button>
</div>
</article>
<!-- Popover Structure -->
<div id="popover-id" popover class="ic-popover">
<button type="button" popovertarget="popover-id" popovertargetaction="hide" class="ic-popover-close">â</button>
<!-- Popover content is rendered here based on type (video, article, etc.) -->
<div class="ic-popover-article">...</div>
</div>
Each card can be customized through the settings
object:
const settings = {
// Schema.org structured data
useSchema: true, // Enable/disable schema markup (default: true)
// Custom styling
styles: {
'cc-headline': 'class="custom-headline text-lg font-bold"',
'cc-summary': 'class="text-gray-600"',
'cc-content': 'class="p-4"'
},
// Responsive image configuration
srcsetBreakpoints: [280, 500, 720, 1080, 1440], // Custom breakpoints
layoutIndex: 0, // Layout position for responsive sizing
layoutSrcsets: [...], // Pre-calculated srcset configurations
layoutSrcset: "...", // Computed srcset for current layout
// Component-specific settings
componentSettings: {
// Card-type specific configurations
}
};
The component uses a consistent CSS class naming convention:
/* Base component classes */
.cc /* Base card container */
.cc-content /* Content area wrapper */
.cc-media /* Media area wrapper */
/* Content elements */
.cc-category /* Content category/tagline */
.cc-headline /* Primary heading */
.cc-subheadline /* Secondary heading */
.cc-summary /* Brief description */
.cc-text /* Detailed content */
/* Metadata and engagement */
.cc-meta /* Publication metadata wrapper */
.cc-published /* Publication date */
.cc-reading-time /* Reading/prep time */
.cc-engagement /* Engagement metrics wrapper */
.cc-reaction /* Reaction buttons */
.cc-comments /* Comment count */
.cc-views /* View count */
/* Attribution */
.cc-authors /* Authors wrapper */
.cc-author /* Individual author */
.cc-avatar /* Author avatar image */
.cc-author-name /* Author name */
.cc-author-role /* Author role/title */
.cc-tags /* Tags wrapper */
.cc-tag /* Individual tag */
/* Actions and links */
.cc-actions /* Actions wrapper */
.cc-action-primary /* Primary action button */
.cc-action-secondary /* Secondary action button */
.cc-links /* Links wrapper */
/* Media elements */
.cc-media-image /* Media images */
.cc-media-video /* Media videos */
.cc-media-caption /* Media captions */
.cc-ribbon /* Ribbon overlays */
.cc-sticker /* Sticker/badge overlays */
/* Type-specific classes */
.cc-recipe-meta /* Recipe metadata */
.cc-recipe-ingredients /* Recipe ingredients */
.cc-recipe-instructions /* Recipe instructions */
.cc-event-location /* Event location */
.cc-event-organizer /* Event organizer */
.cc-business-map /* Business map embed */
.cc-faq /* FAQ wrapper */
.cc-faq-item /* FAQ item */
.cc-faq-title /* FAQ question */
.cc-faq-panel /* FAQ answer */
.cc-timeline /* Timeline wrapper */
.cc-timeline-item /* Timeline item */
.cc-timeline-headline /* Timeline event title */
.cc-timeline-text /* Timeline event description */
.cc-poll-form /* Poll form */
.cc-poll-option /* Poll option */
.cc-poll-results /* Poll results */
The getStyle()
utility function allows dynamic style injection:
// In card render methods
${getStyle('cc-headline', settings)}
// Outputs: class="cc-headline" or custom styles from settings.styles['cc-headline']
// Custom styles example
settings.styles['cc-headline'] = 'class="text-2xl font-bold text-blue-600"';
Cards are designed to be responsive by default:
Cards can integrate with various CSS frameworks and design systems:
const tailwindSettings = {
styles: {
'cc-content': 'class="p-6 bg-white rounded-lg shadow-md"',
'cc-headline': 'class="text-xl font-bold text-gray-900 mb-2"',
'cc-summary': 'class="text-gray-600 leading-relaxed"',
'cc-actions': 'class="flex gap-2 mt-4"',
'cc-action-primary': 'class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"'
}
};
.cc {
--cc-border-radius: 8px;
--cc-padding: 1rem;
--cc-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
--cc-primary-color: #3b82f6;
--cc-text-color: #374151;
}
.cc-content {
padding: var(--cc-padding);
border-radius: var(--cc-border-radius);
box-shadow: var(--cc-shadow);
color: var(--cc-text-color);
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<!-- Article Card -->
<article-card id="article-1"></article-card>
<!-- Recipe Card with custom settings -->
<recipe-card
id="recipe-1"
settings='{"useSchema": true, "styles": {"cc-headline": "class=\"large-title\""}}'>
</recipe-card>
<script type="module">
import './cards/ArticleCard.js';
import './cards/RecipeCard.js';
// Load and set data
fetch('./data.json')
.then(response => response.json())
.then(data => {
const articleCard = document.getElementById('article-1');
const articleData = data.find(item => item.id === 'article-1');
articleCard.dataset = { data: articleData };
const recipeCard = document.getElementById('recipe-1');
const recipeData = data.find(item => item.id === 'recipe-1');
recipeCard.dataset = { data: recipeData };
});
</script>
</body>
</html>
import { ArticleCard } from './cards/ArticleCard.js';
import { RecipeCard } from './cards/RecipeCard.js';
import { BusinessCard } from './cards/BusinessCard.js';
class CardRenderer {
static cardTypes = {
'article': ArticleCard,
'recipe': RecipeCard,
'business': BusinessCard,
// ... other card types
};
static createCard(data, settings = {}) {
const CardClass = this.cardTypes[data.type];
if (!CardClass) {
console.warn(`Unknown card type: ${data.type}`);
return null;
}
const card = new CardClass();
card.dataset = { data, settings };
return card;
}
static renderCards(container, cardsData, globalSettings = {}) {
const fragment = document.createDocumentFragment();
cardsData.forEach(cardData => {
const card = this.createCard(cardData, globalSettings);
if (card) {
fragment.appendChild(card);
}
});
container.appendChild(fragment);
}
}
// Usage
const container = document.getElementById('cards-container');
const cardsData = await fetch('./data.json').then(r => r.json());
const settings = {
useSchema: true,
styles: {
'cc-content': 'class="card-content"'
}
};
CardRenderer.renderCards(container, cardsData, settings);
import { BaseCard } from '../base/BaseCard.js';
import { getStyle, renderActions, renderHeader, renderMedia } from '../base/utils.js';
export class CustomCard extends BaseCard {
constructor() {
super();
}
render() {
const renderContext = this._setSchema('Thing'); // Set appropriate schema
if (!renderContext) return '';
const { settings, useSchema, content, headlineTag } = renderContext;
const { customData = {} } = this.data;
return `
${this.data.media ? renderMedia(this.data.media, this.data.ribbon, this.data.sticker, useSchema, settings) : ''}
<div ${getStyle('cc-content', settings)}>
${renderHeader(content, settings)}
${content.headline ? `<${headlineTag} ${getStyle('cc-headline', settings)} ${useSchema ? 'itemprop="name"' : ''}>${content.headline}</${headlineTag}>` : ''}
<!-- Custom content rendering -->
${customData.specialField ? `<div ${getStyle('cc-custom-field', settings)}>${customData.specialField}</div>` : ''}
${renderActions(this.data.actions, useSchema, settings)}
</div>
`;
}
}
// Register the custom element
customElements.define('custom-card', CustomCard);
dataset
(getter/setter)Sets or gets the complete card data and settings.
card.dataset = { data: cardData, settings: cardSettings };
const { data, settings } = card.dataset;
data
(getter)Returns the cardâs data object.
const cardData = card.data;
settings
(getter)Returns the resolved settings object with defaults applied.
const cardSettings = card.settings;
getStyle(componentName)
Returns the style string for a given component class name.
const headlineStyle = card.getStyle('cc-headline');
// Returns: 'class="cc-headline"' or custom styles
The utils.js
module provides common rendering functions:
renderMedia(media, ribbon, sticker, useSchema, settings)
Renders the media area with images, videos, and overlays.
renderHeader(content, settings)
Renders the category/tagline header section.
renderAuthors(authors, useSchema, settings)
Renders author information with avatars and contact links.
renderEngagement(engagement, useSchema, settings)
Renders engagement metrics (likes, comments, shares, views).
renderTags(tags, settings)
Renders tag links.
renderLinks(links, settings, actions)
Renders navigation links.
renderActions(actions, useSchema, settings)
Renders action buttons with popover support.
getStyle(className, settings)
Returns appropriate style attributes for a given class name.
loading="lazy"
by defaultarticle
, figure
, address
, etc.For complete Umbraco CMS implementation details including document types, compositions, property editors, and deployment strategies, see the dedicated Umbraco Implementation Guide. ````