@x-wave/blog 1.0.36 → 1.0.38

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
@@ -56,6 +56,20 @@ src/
56
56
  ├── welcome.mdx
57
57
  ├── glossary.mdx
58
58
  └── faq.mdx
59
+ public/
60
+ └── og/
61
+ ├── en/ # Language-specific OG images
62
+ │ ├── welcome-preview.png
63
+ │ ├── glossary-preview.png
64
+ │ └── faq-preview.png
65
+ ├── es/
66
+ │ ├── welcome-preview.png
67
+ │ ├── glossary-preview.png
68
+ │ └── faq-preview.png
69
+ └── zh/
70
+ ├── welcome-preview.png
71
+ ├── glossary-preview.png
72
+ └── faq-preview.png
59
73
  ```
60
74
 
61
75
  ### 2. Set up i18n and styles
@@ -250,8 +264,11 @@ Regular content here.
250
264
  | Field | Type | Description |
251
265
  |---|---|---|
252
266
  | `title` | `string` | Document title (informational, not displayed by framework) |
267
+ | `description` | `string` | Optional SEO description for the article. Used in the page `<meta name="description">` tag. Falls back to site-level description if not provided. |
253
268
  | `author` | `string` | Author name. Displayed below the page title with a user icon. |
254
269
  | `date` | `string` | Publication or update date. Displayed below the page title with "Last edited" label and calendar icon (i18n supported). |
270
+ | `keywords` | `string[] \| string` | Optional array of keywords or comma-separated string for SEO. Inserted into the page `<meta name="keywords">` tag. |
271
+ | `ogImage` | `string` | Optional Open Graph image filename (just the filename, not the full path). Images should be stored in `public/og/<language>/` folder. Used for social media sharing previews. |
255
272
  | `hasAdvanced` | `boolean` | Enables Simple/Advanced mode toggle. Requires a `-advanced.mdx` variant. |
256
273
  | `tags` | `string[]` | Array of tag strings for categorizing content. Tags are automatically indexed by the framework when you pass `mdxFiles` to BlogProvider. Tags are clickable and show search results. |
257
274
 
@@ -390,6 +407,7 @@ All CSS variables are scoped to `.xw-blog-root` for isolation and to prevent con
390
407
  ```ts
391
408
  interface BlogConfig {
392
409
  title: string // Site title
410
+ description?: string // Optional default description for SEO (used as fallback if article has no description)
393
411
  logo?: React.ComponentType<{ className?: string }> // Optional logo
394
412
  supportedLanguages: readonly string[] // e.g. ['en', 'es', 'zh']
395
413
  navigationData: NavigationEntry[] // Menu structure
@@ -406,6 +424,7 @@ interface BlogConfig {
406
424
  **Key properties:**
407
425
 
408
426
  - **`header`**: Optional. If omitted entirely, the built-in header component will not be rendered. Use this when you want to implement a custom header.
427
+ - **`description`**: Optional. Default SEO description used in the page `<meta name="description">` tag. Articles can override this with their own `description` in frontmatter.
409
428
  - **`contentMaxWidth`**: Optional. Set a custom maximum width for the main content area. Example: `'100rem'` or `'1400px'`. Default: `'80rem'`.
410
429
  - **`defaultRoute`**: Optional. Controls which page displays at the root path (`/`):
411
430
  - Set to `'latest'` (default) to show the HomePage listing the latest articles
@@ -440,9 +459,79 @@ title: Getting Started
440
459
  author: Jane Doe
441
460
  date: 2026-02-23
442
461
  description: Learn the basics in 5 minutes
462
+ keywords: [getting started, tutorial, basics]
443
463
  ---
444
464
  ```
445
465
 
466
+ ### SEO and metadata
467
+
468
+ The framework automatically handles SEO metadata using React Helmet. Page `<title>`, `<meta description>`, `<meta keywords>`, and Open Graph tags are set based on article frontmatter and site configuration.
469
+
470
+ **Article pages:**
471
+ - **Title**: `"{article title} | {site title}"` (if title exists in frontmatter)
472
+ - **Description**: Uses article `description` from frontmatter, falls back to site-level `description` from config
473
+ - **Keywords**: Uses article `keywords` from frontmatter (converts array to comma-separated string)
474
+ - **Open Graph Image**: Uses article `ogImage` filename (image path is auto-constructed from language folder)
475
+
476
+ **Open Graph tags (for social media sharing):**
477
+ When an article includes an `ogImage`, the framework automatically generates:
478
+ - `og:image` - The full image URL for social media preview
479
+ - `og:title` - The article title
480
+ - `twitter:card` - Set to `summary_large_image` for Twitter/X preview
481
+ - `twitter:image` - The image URL for Twitter/X sharing
482
+
483
+ **Home page:**
484
+ - **Title**: Site title from config
485
+ - **Description**: Uses site-level `description` from config
486
+
487
+ Image folder structure for serving OG images:
488
+
489
+ ```
490
+ public/og/
491
+ ├── en/
492
+ │ ├── getting-started.png # Served as /og/en/getting-started.png
493
+ │ └── tutorial.png # Served as /og/en/tutorial.png
494
+ ├── es/
495
+ │ └── getting-started.png # Served as /og/es/getting-started.png
496
+ └── zh/
497
+ └── getting-started.png # Served as /og/zh/getting-started.png
498
+ ```
499
+
500
+ Example setup:
501
+
502
+ ```tsx
503
+ // app.tsx
504
+ <BlogProvider
505
+ config={{
506
+ title: 'My Documentation',
507
+ description: 'Complete guide to our platform', // Fallback description
508
+ supportedLanguages: ['en', 'es'],
509
+ navigationData: NAVIGATION_DATA,
510
+ }}
511
+ blog={blog}
512
+ >
513
+ ```
514
+
515
+ Then in your MDX frontmatter:
516
+
517
+ ```mdx
518
+ ---
519
+ title: Getting Started
520
+ author: Jane Doe
521
+ date: 2026-02-23
522
+ description: Step-by-step guide to getting started in 5 minutes
523
+ keywords: [getting started, setup, tutorial, beginners]
524
+ ogImage: getting-started.png // Image at /og/en/getting-started.png (or /og/es/, /og/zh/)
525
+ ---
526
+ ```
527
+
528
+ When users share this article on social media:
529
+ - Facebook will show the title, description, and the OG image
530
+ - Twitter/X will show a large image preview with the article title
531
+ - LinkedIn and other platforms will use the OG metadata for rich previews
532
+
533
+ This ensures proper SEO for search engines and rich sharing previews on social media, with full support for multi-language content.
534
+
446
535
  ### Custom headers
447
536
 
448
537
  If you need a custom header instead of the built-in one, simply omit the `header` config and use the provided hooks: