# Blog and comments

## Requirements

A theme declares blog rendering support by using `<gs-blog>` in its Loom files. The compiler detects this element and writes `supports_blog` into the package registry. After `npm run themes:build`, run `php artisan themes:sync` from `api`. Enable Blog for the workspace. Loom markup does not grant access to a plugin.

## Archive: sections/journal.html

```html
<section class="theme-journal">
  <gs-blog variant="blog-grid-sidebar"></gs-blog>
</section>
```

`*.schema.json`:

```json
{
  "name": "Blog",
  "settings": [],
  "presets": [
    {
      "name": "Blog"
    }
  ]
}
```

## Page: templates/blog.json

```json
{"title":"Blog","role":"blog","sections":{"journal":{"type":"journal"}},"order":["journal"]}
```

For an article page, use `role: "blog-details"`. These roles support navigation, sitemap discovery and hiding blog pages when Blog is disabled. A fresh package installation creates these pages; upgrading a package does not automatically add pages to existing customer sites. Add a page with a blog layout and a blog section to an existing site.

## Variants and addresses

`blog-grid-sidebar` and `blog-list-sidebar` display a list, or an article when a post is selected. `blog-detail-sidebar` is a detail view. For custom compositions use `blog-cards`, `blog-list`, `blog-article`, `blog-search`, `blog-categories`, `blog-tags`, `blog-recent`, `blog-pagination`, `blog-author` and `blog-post-footer`.

An article URL looks like `/article?post=post-slug`. The renderer finds archive and detail destinations through page roles. The API accepts `post`, `page`, `search`, `category`, `tag`. Shared components generate links and search forms; never fetch private endpoints from theme files. Public responses exclude drafts and posts scheduled for the future.

## Comments plugin

```html
<gs-blog variant="blog-article"></gs-blog>
<gs-comments></gs-comments>
```

Enable Blog, Comments and comments on the individual post. Only approved comments are visible. The reply form uses GrowSite validation, protection and endpoints. Submission is disabled in builder preview. Sidebar variants already include comments in their detail view, so do not add another `gs-comments` there.

## Theme styling for Blog and Comments

`gs-blog` and `gs-comments` provide shared content, navigation and form behavior. They do not automatically reproduce your theme's visual design. Put the plugin styles in your theme package, for example `assets/blog.css`. GS Loom loads CSS from `assets/` inside the theme scope; keep selectors limited to the relevant components so other sections retain their appearance.

Cover the complete reading experience:

| Element | CSS selectors |
| --- | --- |
| List and article layout | `.blog-layout`, `.blog-posts`, `.blog-grid`, `.blog-article` |
| Cover and recent images | `.blog-image`, `.blog-recent img` |
| Search, categories and sidebar | `.blog-search`, `.blog-widget`, `.blog-sidebar` |
| Tags, sharing and pagination | `.blog-tags a`, `.blog-share a`, `.blog-pagination` |
| Author and adjacent posts | `.blog-author`, `.blog-post-navigation` |
| Comments and reply form | `.blog-comments`, `.blog-form-row`, `.blog-avatar`, `.blog-submit` |

GrowSite Skeleton includes its own `assets/blog.css` for both `templates/blog.json` and `templates/article.json`. It uses rounded dark cards, accent-colored tags and buttons, rounded images, and a comment form matching the Instant theme. The file also styles rich-text code blocks. Download the complete [GrowSite Skeleton package](/downloads/growsite-skeleton.zip) to inspect the implementation and its theme variables.

For example, Skeleton styles the shared search component without replacing its form:

```css
.sk-page .blog-section .blog-search {
  border: 1px solid var(--sk-border);
  border-radius: 50px;
  background: var(--sk-surface);
}
.sk-page .blog-section .blog-search input {
  font-size: 16px;
  color: var(--sk-text);
  background: transparent;
}
```

The `--sk-*` variables belong to Skeleton; define your own tokens when adapting this example to another theme. Give the input an explicit readable font size: the shared search label hides its visible text with `font-size: 0`, while its accessible name remains available.

Style hover, keyboard focus, disabled controls and narrow layouts. Preserve the shared form submission, validation and plugin access checks. On phones, stack the sidebar and comment fields, allow tags to wrap, and keep long content inside the page. See [code block styling](/en/text/#code-blocks-and-inline-code) for rich-text code.

## Verification and SEO

Create a published post, a draft and a future-dated post. Test the list, search, categories, pagination and article. Check empty lists, disabled comments, moderation and invalid replies. Disabling Blog removes pages with blog roles from public navigation without deleting content. GrowSite generates article metadata and canonical URLs; see [SEO](/en/seo-plugins/).
