@fullstackdatasolutions/articles 0.3.0 → 0.4.3

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
@@ -62,8 +62,11 @@ export const siteConfig: ArticlesConfig = {
62
62
 
63
63
  ```tsx
64
64
  // app/articles/page.tsx
65
+ import type { Metadata } from 'next'
65
66
  import { ArticlesPage } from '@fullstackdatasolutions/articles'
67
+ import { generateArticlesIndexMetadata } from '@fullstackdatasolutions/articles/server'
66
68
  import { siteConfig } from '@/config/articles'
69
+ export const metadata: Metadata = generateArticlesIndexMetadata(siteConfig)
67
70
  export default function Page() {
68
71
  return <ArticlesPage config={siteConfig} />
69
72
  }
@@ -173,7 +176,7 @@ hero: {
173
176
 
174
177
  ## ArticleDetailHero
175
178
 
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.
179
+ `ArticleDetailHero` renders the article's featured image full-width behind the title, category tags, and metadata (date, read time, author). When you render `ArticleDetailHero` exactly as shown below the hero image and linked categories appear automatically—no additional styling or extra `<Link>` wiring is required in the consuming app. Just pass the article payload and `categoryBasePath` (defaults to `/articles/category`) so the tags render as links.
177
180
 
178
181
  ```tsx
179
182
  import { ArticleDetailHero } from '@fullstackdatasolutions/articles'
@@ -187,10 +190,61 @@ import { ArticleDetailHero } from '@fullstackdatasolutions/articles'
187
190
  | Prop | Type | Required | Description |
188
191
  |---|---|---|---|
189
192
  | `article` | `Article` | yes | Article object returned by `getArticleMetadata` |
190
- | `categoryBasePath` | `string` | no | Base path for category links (e.g. `"/articles/category"`). Omit to render categories as plain text. |
193
+ | `categoryBasePath` | `string` | no | Base path for category links. Defaults to `"/articles/category"`. Pass `""` to render categories as plain text. |
194
+ | `showDate` | `boolean` | no | Show the article date. Defaults to `false` (hidden). |
191
195
 
192
196
  - Category tags are capped at 4. When an article has more than 4 categories, only the first 4 are shown.
197
+ - The date field is hidden by default. Pass `showDate={true}` to display it.
193
198
  - All layout styles are inline so the component renders correctly regardless of whether `@source` is configured for the package.
199
+ - Hero image / categories behave automatically once you use this component; apps do not need to reimplement the hero section for those features.
200
+
201
+ ---
202
+
203
+ ## ArticleSocialShare
204
+
205
+ `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`.
206
+
207
+ ```tsx
208
+ import { ArticleSocialShare } from '@fullstackdatasolutions/articles'
209
+
210
+ <ArticleSocialShare
211
+ title={article.title}
212
+ url={articleUrl}
213
+ excerpt={article.excerpt}
214
+ shareMessage="Optional footer note shown below the buttons."
215
+ />
216
+ ```
217
+
218
+ | Prop | Type | Required | Description |
219
+ |---|---|---|---|
220
+ | `title` | `string` | yes | Article title - used in share text |
221
+ | `url` | `string` | yes | Canonical URL to share |
222
+ | `excerpt` | `string` | no | Used as email body pre-fill |
223
+ | `shareMessage` | `string` | no | Optional paragraph rendered below the share buttons |
224
+
225
+ ---
226
+
227
+ ## ArticleNavigation
228
+
229
+ `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.
230
+
231
+ ```tsx
232
+ import { ArticleNavigation } from '@fullstackdatasolutions/articles'
233
+ import { getAdjacentArticles } from '@fullstackdatasolutions/articles/server'
234
+
235
+ const { previous, next } = await getAdjacentArticles(slug)
236
+
237
+ <ArticleNavigation previous={previous} next={next} basePath="/articles" />
238
+ ```
239
+
240
+ | Prop | Type | Required | Description |
241
+ |---|---|---|---|
242
+ | `previous` | `{ slug: string; title: string } \| null` | yes | Previous article, or `null` |
243
+ | `next` | `{ slug: string; title: string } \| null` | yes | Next article, or `null` |
244
+ | `basePath` | `string` | yes | Route prefix (e.g. `"/articles"`) prepended to each slug |
245
+
246
+ - Titles longer than 60 characters are truncated with an ellipsis.
247
+ - No output is rendered when both `previous` and `next` are `null`.
194
248
 
195
249
  ---
196
250
 
@@ -226,6 +280,21 @@ app/api/articles/[slug]/comments/[commentId]/route.ts ← DELETE (soft)
226
280
 
227
281
  ## SEO utilities
228
282
 
283
+ ### Articles index metadata
284
+
285
+ ```ts
286
+ // app/articles/page.tsx
287
+ import type { Metadata } from 'next'
288
+ import { generateArticlesIndexMetadata } from '@fullstackdatasolutions/articles/server'
289
+ import { siteConfig } from '@/config/articles'
290
+ export const metadata: Metadata = generateArticlesIndexMetadata(siteConfig)
291
+ // Produces: title, description, full OpenGraph (type: 'website'), Twitter Card,
292
+ // canonical URL (/articles), and robots directives.
293
+ // Description falls back to config.hero?.description when set.
294
+ ```
295
+
296
+ ### Article and category metadata
297
+
229
298
  ```ts
230
299
  // app/articles/[slug]/page.tsx
231
300
  import { generateArticleMetadata } from '@fullstackdatasolutions/articles/server'
@@ -237,15 +306,31 @@ export const generateMetadata = ({ params }) =>
237
306
  import { generateCategoryMetadata } from '@fullstackdatasolutions/articles/server'
238
307
  export const generateMetadata = ({ params }) =>
239
308
  generateCategoryMetadata(params.category, siteConfig)
309
+ ```
310
+
311
+ ### Sitemaps
240
312
 
313
+ Use `getArticleSitemapEntries` to generate article and category sitemap entries. Pass your `ArticlesConfig` object (preferred) or a plain URL string.
314
+
315
+ ```ts
241
316
  // app/sitemap.ts
242
317
  import { getArticleSitemapEntries } from '@fullstackdatasolutions/articles/server'
243
- export default async function sitemap() {
244
- return getArticleSitemapEntries('https://yoursite.com')
245
- // Returns both article entries (priority 0.8) and category entries (priority 0.7)
318
+ import { siteConfig } from '@/config/articles'
319
+ import type { MetadataRoute } from 'next'
320
+
321
+ const staticPages: MetadataRoute.Sitemap = [
322
+ { url: 'https://yoursite.com', changeFrequency: 'weekly', priority: 1.0 },
323
+ { url: 'https://yoursite.com/about', changeFrequency: 'monthly', priority: 0.8 },
324
+ ]
325
+
326
+ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
327
+ const articleEntries = await getArticleSitemapEntries(siteConfig)
328
+ return [...staticPages, ...articleEntries]
246
329
  }
247
330
  ```
248
331
 
332
+ 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')`.
333
+
249
334
  JSON-LD structured data (`ArticleSchema`, `BreadcrumbSchema`, `CollectionPageSchema`) is rendered automatically inside the library components — no extra wiring required.
250
335
 
251
336
  ---
@@ -278,6 +363,7 @@ import {
278
363
  searchArticles,
279
364
  categoryToSlug,
280
365
  getArticleSitemapEntries,
366
+ generateArticlesIndexMetadata,
281
367
  generateArticleMetadata,
282
368
  generateCategoryMetadata,
283
369
  } from '@fullstackdatasolutions/articles/server'
@@ -330,7 +416,10 @@ This app uses `@fullstackdatasolutions/articles` for the articles section.
330
416
  The package ships its source TypeScript files so Tailwind can scan them.
331
417
  `app/globals.css` contains:
332
418
  @source "./node_modules/@fullstackdatasolutions/articles/src";
333
- 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.
419
+ 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.
420
+
421
+ ### Server utilities
422
+ For sitemaps and metadata: `import { getArticleSitemapEntries, generateArticlesIndexMetadata, generateArticleMetadata, generateCategoryMetadata } from '@fullstackdatasolutions/articles/server'`. See README for usage examples.
334
423
 
335
424
  ### Rules
336
425
  - Change `config/articles.ts` first; only edit library source if config cannot express the need.