@studiocms/blog 0.1.0-beta.25 → 0.1.0-beta.26

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.
@@ -9,6 +9,7 @@ import {
9
9
  headDefaults,
10
10
  } from 'studiocms:lib';
11
11
  import type { z } from 'astro/zod';
12
+ import { getHeroImage } from './heroHelper.js';
12
13
 
13
14
  let htmlDefaultHead: HeadUserConfig = [];
14
15
  let favicon = '';
@@ -31,14 +32,11 @@ interface Props {
31
32
 
32
33
  const canonicalURL = Astro.url;
33
34
 
34
- const {
35
- title,
36
- description,
37
- lang = 'en',
38
- image = 'https://images.unsplash.com/photo-1707343843982-f8275f3994c5?q=80&w=1032&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
39
- } = Astro.props;
35
+ const { title, description, lang = 'en', image } = Astro.props;
40
36
 
41
- const makeHeader = headDefaults(title, description, lang, Astro, favicon, image, canonicalURL);
37
+ const ogImage = getHeroImage(image, Astro);
38
+
39
+ const makeHeader = headDefaults(title, description, lang, Astro, favicon, ogImage, canonicalURL);
42
40
 
43
41
  const StudioCMSFrontEndHeads: z.input<ReturnType<typeof HeadConfigSchema>> = [
44
42
  // Fonts
@@ -4,6 +4,7 @@ import { FormattedDate } from 'studiocms:components';
4
4
  import { CustomImage } from 'studiocms:imageHandler/components';
5
5
  import { pathWithBase } from 'studiocms:lib';
6
6
  import type { CombinedPageData } from 'studiocms:sdk/types';
7
+ import { getHeroImage } from './heroHelper.js';
7
8
 
8
9
  const blogRouteFullPath = `${blogConfig.route}/[...slug]`;
9
10
 
@@ -26,7 +27,7 @@ const { blogPageList } = Astro.props;
26
27
  blogPageList.length > 0 && blogPageList.map(({slug, heroImage, title, description, publishedAt}) => (
27
28
  <li>
28
29
  <a href={pathWithBase(getBlogRoute(slug))}>
29
- <CustomImage src={heroImage} alt={title} width={720} height={360}/>
30
+ <CustomImage src={getHeroImage(heroImage, Astro)} alt={title} width={720} height={360}/>
30
31
  <div>
31
32
  <span class="title">{title}</span>
32
33
  <span class="date"> <FormattedDate date={publishedAt} /> </span>
@@ -1,21 +1,24 @@
1
1
  ---
2
2
  import { FormattedDate } from 'studiocms:components';
3
3
  import { CustomImage } from 'studiocms:imageHandler/components';
4
+ import { getHeroImage } from './heroHelper.js';
4
5
 
5
6
  interface Props {
6
7
  title: string;
7
8
  publishedAt: Date;
8
9
  updatedAt?: Date | null;
9
- heroImage: string;
10
+ heroImage?: string;
10
11
  description: string;
11
12
  }
12
13
 
13
14
  const { title, description, heroImage, publishedAt, updatedAt } = Astro.props;
15
+
16
+ const heroImageToUse = getHeroImage(heroImage, Astro);
14
17
  ---
15
18
  <h1 class="title">{title}</h1>
16
19
 
17
20
  <div style="text-align: center;">
18
- <CustomImage src={heroImage} alt={title} width={720} height={360}/>
21
+ <CustomImage src={heroImageToUse} alt={title} width={720} height={360}/>
19
22
  <div>
20
23
  <p class="date">Published: <FormattedDate date={publishedAt}/></p>
21
24
  {updatedAt && <p class="date"> | Last Updated: <FormattedDate date={updatedAt}/></p>}
@@ -0,0 +1 @@
1
+ export declare const FALLBACK_OG_IMAGE = "https://images.unsplash.com/photo-1707343843982-f8275f3994c5?q=80&w=1032&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D";
@@ -0,0 +1,4 @@
1
+ const FALLBACK_OG_IMAGE = "https://images.unsplash.com/photo-1707343843982-f8275f3994c5?q=80&w=1032&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D";
2
+ export {
3
+ FALLBACK_OG_IMAGE
4
+ };
@@ -0,0 +1,22 @@
1
+ import type { AstroGlobal } from 'astro';
2
+ /**
3
+ * Trims leading and trailing whitespace from the given input string.
4
+ *
5
+ * @param input - The string to trim. Can be `string`, `null`, or `undefined`.
6
+ * @returns The trimmed string, or `undefined` if the input is `null` or `undefined`.
7
+ */
8
+ export declare function trimInput(input: string | null | undefined): string | undefined;
9
+ /**
10
+ * Retrieves the appropriate hero image URL based on the provided `hero` string,
11
+ * the site's default OG image, or a fallback image.
12
+ *
13
+ * The function checks the following, in order:
14
+ * 1. If a valid `hero` image URL is provided, it returns that.
15
+ * 2. If not, it attempts to use the site's default OG image from the Astro global context.
16
+ * 3. If neither is available, it returns a constant fallback image URL.
17
+ *
18
+ * @param hero - The primary hero image URL, or `undefined` if not provided.
19
+ * @param Astro - The Astro global context, used to access site configuration.
20
+ * @returns The resolved hero image URL as a string.
21
+ */
22
+ export declare function getHeroImage(hero: string | undefined, Astro: AstroGlobal): string;
@@ -0,0 +1,17 @@
1
+ import { FALLBACK_OG_IMAGE } from "./consts.js";
2
+ function trimInput(input) {
3
+ if (input == null) return void 0;
4
+ const trimmed = input.trim();
5
+ return trimmed.length > 0 ? trimmed : void 0;
6
+ }
7
+ function getHeroImage(hero, Astro) {
8
+ const primary = trimInput(hero);
9
+ const siteFallback = trimInput(Astro.locals?.StudioCMS?.siteConfig?.data?.defaultOgImage);
10
+ if (primary) return primary;
11
+ if (siteFallback) return siteFallback;
12
+ return FALLBACK_OG_IMAGE;
13
+ }
14
+ export {
15
+ getHeroImage,
16
+ trimInput
17
+ };
@@ -9,12 +9,14 @@ if (!slug) {
9
9
  slug = 'index';
10
10
  }
11
11
 
12
- const { data: page } = await runSDK(SDKCoreJs.GET.page.bySlug(slug));
12
+ const fullPageData = await runSDK(SDKCoreJs.GET.page.bySlug(slug));
13
13
 
14
- if (!page) {
14
+ if (!fullPageData) {
15
15
  return new Response(null, { status: 404 });
16
16
  }
17
17
 
18
+ const page = fullPageData.data;
19
+
18
20
  const { title, description, heroImage } = page;
19
21
  ---
20
22
 
@@ -14,13 +14,15 @@ if (!slug) {
14
14
 
15
15
  // Fetch the blog post content
16
16
 
17
- const { data: post } = await runSDK(SDKCoreJs.GET.page.bySlug(slug));
17
+ const fullPageData = await runSDK(SDKCoreJs.GET.page.bySlug(slug));
18
18
 
19
19
  // If no content is found, redirect to 404
20
- if (!post) {
20
+ if (!fullPageData) {
21
21
  return new Response(null, { status: 404 });
22
22
  }
23
23
 
24
+ const post = fullPageData.data;
25
+
24
26
  const { title, description, heroImage, publishedAt, updatedAt } = post;
25
27
  ---
26
28
 
package/dist/types.d.ts CHANGED
@@ -19,13 +19,13 @@ export declare const FrontEndConfigSchema: z.ZodDefault<z.ZodOptional<z.ZodObjec
19
19
  attrs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodBoolean, z.ZodUndefined]>>>;
20
20
  content: z.ZodDefault<z.ZodString>;
21
21
  }, "strip", z.ZodTypeAny, {
22
- tag: "title" | "link" | "base" | "meta" | "noscript" | "script" | "style" | "template";
23
- content: string;
22
+ tag: "title" | "base" | "link" | "style" | "meta" | "script" | "noscript" | "template";
24
23
  attrs: Record<string, string | boolean | undefined>;
24
+ content: string;
25
25
  }, {
26
- tag: "title" | "link" | "base" | "meta" | "noscript" | "script" | "style" | "template";
27
- content?: string | undefined;
26
+ tag: "title" | "base" | "link" | "style" | "meta" | "script" | "noscript" | "template";
28
27
  attrs?: Record<string, string | boolean | undefined> | undefined;
28
+ content?: string | undefined;
29
29
  }>, "many">>;
30
30
  /**
31
31
  * Favicon Configuration - The default favicon configuration for the Frontend
@@ -71,9 +71,9 @@ export declare const FrontEndConfigSchema: z.ZodDefault<z.ZodOptional<z.ZodObjec
71
71
  }, "strip", z.ZodTypeAny, {
72
72
  htmlDefaultLanguage: string;
73
73
  htmlDefaultHead: {
74
- tag: "title" | "link" | "base" | "meta" | "noscript" | "script" | "style" | "template";
75
- content: string;
74
+ tag: "title" | "base" | "link" | "style" | "meta" | "script" | "noscript" | "template";
76
75
  attrs: Record<string, string | boolean | undefined>;
76
+ content: string;
77
77
  }[];
78
78
  favicon: string;
79
79
  sitemap: boolean;
@@ -86,9 +86,9 @@ export declare const FrontEndConfigSchema: z.ZodDefault<z.ZodOptional<z.ZodObjec
86
86
  }, {
87
87
  htmlDefaultLanguage?: string | undefined;
88
88
  htmlDefaultHead?: {
89
- tag: "title" | "link" | "base" | "meta" | "noscript" | "script" | "style" | "template";
90
- content?: string | undefined;
89
+ tag: "title" | "base" | "link" | "style" | "meta" | "script" | "noscript" | "template";
91
90
  attrs?: Record<string, string | boolean | undefined> | undefined;
91
+ content?: string | undefined;
92
92
  }[] | undefined;
93
93
  favicon?: string | undefined;
94
94
  sitemap?: boolean | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studiocms/blog",
3
- "version": "0.1.0-beta.25",
3
+ "version": "0.1.0-beta.26",
4
4
  "description": "Add a blog to your StudioCMS project with ease!",
5
5
  "author": {
6
6
  "name": "withstudiocms",
@@ -60,10 +60,10 @@
60
60
  },
61
61
  "peerDependencies": {
62
62
  "astro": "^5.12.9",
63
- "effect": "^3.17.9",
63
+ "effect": "^3.17.13",
64
64
  "vite": "^6.3.4",
65
- "@studiocms/md": "0.1.0-beta.25",
66
- "studiocms": "0.1.0-beta.25"
65
+ "@studiocms/md": "0.1.0-beta.26",
66
+ "studiocms": "0.1.0-beta.26"
67
67
  },
68
68
  "scripts": {
69
69
  "build": "buildkit build 'src/**/*.{ts,astro,css,json,png,d.ts}'",