@fullstackdatasolutions/articles 0.2.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -171,6 +171,79 @@ hero: {
171
171
 
172
172
  ---
173
173
 
174
+ ## ArticleDetailHero
175
+
176
+ `ArticleDetailHero` renders the article's featured image full-width behind the title, category tags, and metadata (date, read time, author). Use it in your `app/articles/[slug]/page.tsx` instead of building a custom hero.
177
+
178
+ ```tsx
179
+ import { ArticleDetailHero } from '@fullstackdatasolutions/articles'
180
+
181
+ <ArticleDetailHero
182
+ article={article}
183
+ categoryBasePath="/articles/category"
184
+ />
185
+ ```
186
+
187
+ | Prop | Type | Required | Description |
188
+ |---|---|---|---|
189
+ | `article` | `Article` | yes | Article object returned by `getArticleMetadata` |
190
+ | `categoryBasePath` | `string` | no | Base path for category links. Defaults to `"/articles/category"`. Pass `""` to render categories as plain text. |
191
+ | `showDate` | `boolean` | no | Show the article date. Defaults to `false` (hidden). |
192
+
193
+ - Category tags are capped at 4. When an article has more than 4 categories, only the first 4 are shown.
194
+ - The date field is hidden by default. Pass `showDate={true}` to display it.
195
+ - All layout styles are inline so the component renders correctly regardless of whether `@source` is configured for the package.
196
+
197
+ ---
198
+
199
+ ## ArticleSocialShare
200
+
201
+ `ArticleSocialShare` renders a row of sharing buttons (LinkedIn, Facebook, Twitter, Reddit, WhatsApp, Telegram, Email, Copy Link). Use it below the article body in your `app/articles/[slug]/page.tsx`.
202
+
203
+ ```tsx
204
+ import { ArticleSocialShare } from '@fullstackdatasolutions/articles'
205
+
206
+ <ArticleSocialShare
207
+ title={article.title}
208
+ url={articleUrl}
209
+ excerpt={article.excerpt}
210
+ shareMessage="Optional footer note shown below the buttons."
211
+ />
212
+ ```
213
+
214
+ | Prop | Type | Required | Description |
215
+ |---|---|---|---|
216
+ | `title` | `string` | yes | Article title - used in share text |
217
+ | `url` | `string` | yes | Canonical URL to share |
218
+ | `excerpt` | `string` | no | Used as email body pre-fill |
219
+ | `shareMessage` | `string` | no | Optional paragraph rendered below the share buttons |
220
+
221
+ ---
222
+
223
+ ## ArticleNavigation
224
+
225
+ `ArticleNavigation` renders previous/next article links at the bottom of an article. Returns `null` when both `previous` and `next` are absent (no output, no wrapper element). Use `getAdjacentArticles` from the server entry to fetch the data.
226
+
227
+ ```tsx
228
+ import { ArticleNavigation } from '@fullstackdatasolutions/articles'
229
+ import { getAdjacentArticles } from '@fullstackdatasolutions/articles/server'
230
+
231
+ const { previous, next } = await getAdjacentArticles(slug)
232
+
233
+ <ArticleNavigation previous={previous} next={next} basePath="/articles" />
234
+ ```
235
+
236
+ | Prop | Type | Required | Description |
237
+ |---|---|---|---|
238
+ | `previous` | `{ slug: string; title: string } \| null` | yes | Previous article, or `null` |
239
+ | `next` | `{ slug: string; title: string } \| null` | yes | Next article, or `null` |
240
+ | `basePath` | `string` | yes | Route prefix (e.g. `"/articles"`) prepended to each slug |
241
+
242
+ - Titles longer than 60 characters are truncated with an ellipsis.
243
+ - No output is rendered when both `previous` and `next` are `null`.
244
+
245
+ ---
246
+
174
247
  ## Comments setup
175
248
 
176
249
  ### 1. Enable in config
@@ -203,6 +276,8 @@ app/api/articles/[slug]/comments/[commentId]/route.ts ← DELETE (soft)
203
276
 
204
277
  ## SEO utilities
205
278
 
279
+ ### Article and category metadata
280
+
206
281
  ```ts
207
282
  // app/articles/[slug]/page.tsx
208
283
  import { generateArticleMetadata } from '@fullstackdatasolutions/articles/server'
@@ -214,15 +289,31 @@ export const generateMetadata = ({ params }) =>
214
289
  import { generateCategoryMetadata } from '@fullstackdatasolutions/articles/server'
215
290
  export const generateMetadata = ({ params }) =>
216
291
  generateCategoryMetadata(params.category, siteConfig)
292
+ ```
293
+
294
+ ### Sitemaps
217
295
 
296
+ Use `getArticleSitemapEntries` to generate article and category sitemap entries. Pass your `ArticlesConfig` object (preferred) or a plain URL string.
297
+
298
+ ```ts
218
299
  // app/sitemap.ts
219
300
  import { getArticleSitemapEntries } from '@fullstackdatasolutions/articles/server'
220
- export default async function sitemap() {
221
- return getArticleSitemapEntries('https://yoursite.com')
222
- // Returns both article entries (priority 0.8) and category entries (priority 0.7)
301
+ import { siteConfig } from '@/config/articles'
302
+ import type { MetadataRoute } from 'next'
303
+
304
+ const staticPages: MetadataRoute.Sitemap = [
305
+ { url: 'https://yoursite.com', changeFrequency: 'weekly', priority: 1.0 },
306
+ { url: 'https://yoursite.com/about', changeFrequency: 'monthly', priority: 0.8 },
307
+ ]
308
+
309
+ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
310
+ const articleEntries = await getArticleSitemapEntries(siteConfig)
311
+ return [...staticPages, ...articleEntries]
223
312
  }
224
313
  ```
225
314
 
315
+ Returns article entries (priority 0.8, changeFrequency 'weekly') and category entries (priority 0.7, changeFrequency 'weekly'). Alternative: pass a plain URL string instead of `siteConfig`: `getArticleSitemapEntries('https://yoursite.com')`.
316
+
226
317
  JSON-LD structured data (`ArticleSchema`, `BreadcrumbSchema`, `CollectionPageSchema`) is rendered automatically inside the library components — no extra wiring required.
227
318
 
228
319
  ---
@@ -234,7 +325,7 @@ JSON-LD structured data (`ArticleSchema`, `BreadcrumbSchema`, `CollectionPageSch
234
325
  | `title` | `string` | yes | Article title |
235
326
  | `excerpt` | `string` | yes | One-sentence summary for cards and meta |
236
327
  | `author` | `string` | no | Defaults to `'Andrew Blase'` |
237
- | `tags` | `string[]` | no | Used as categories. First tag = primary category. |
328
+ | `tags` | `string[]` | no | Used as categories. First tag = primary category. ArticleDetailHero displays at most 4 category tags; articles with more than 4 show only the first 4 in the hero. |
238
329
  | `date` | `YYYY-MM-DD` | no | Omit to publish immediately. Future dates hide until that date. |
239
330
  | `featuredImage` | `string` | no | Filename relative to the article directory. Auto-detected if omitted. |
240
331
 
@@ -307,7 +398,10 @@ This app uses `@fullstackdatasolutions/articles` for the articles section.
307
398
  The package ships its source TypeScript files so Tailwind can scan them.
308
399
  `app/globals.css` contains:
309
400
  @source "./node_modules/@fullstackdatasolutions/articles/src";
310
- If this line is missing, most component classes will not render correctly. Note: `ArticleCategoryGrid` image containers use inline styles for critical layout so images remain visible, but all other styling still requires this line.
401
+ If this line is missing, most component classes will not render correctly. Note: `ArticleCategoryGrid` images, `CategoryArticlesPage` hero, and `ArticleDetailHero` image use inline styles for critical layout so they render correctly without this line. All other styling still requires it.
402
+
403
+ ### Server utilities
404
+ For sitemaps and metadata: `import { getArticleSitemapEntries, generateArticleMetadata, generateCategoryMetadata } from '@fullstackdatasolutions/articles/server'`. See README for usage examples.
311
405
 
312
406
  ### Rules
313
407
  - Change `config/articles.ts` first; only edit library source if config cannot express the need.