Skip to content

Commit 9a8b31f

Browse files
author
Michał Gryczka
committed
Enhance blog component and pages: refactor MoreStories component to include default image handling and description truncation, improve blog post layout with structured data for SEO, and update styles for better readability and engagement. Add tags to blog posts for improved categorization and searchability.
1 parent 850a5ce commit 9a8b31f

15 files changed

+577
-190
lines changed

src/components/MoreStories.astro

Lines changed: 120 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ interface Props {
88
99
const { currentSlug, posts } = Astro.props;
1010
11+
// Default fallback image
12+
const defaultImage = "/images/png/defguard.png";
13+
14+
// Get image for a post
15+
const getPostImage = (post: CollectionEntry<"blog">) => {
16+
return post.data.image || defaultImage;
17+
};
18+
1119
// Format date function
1220
const formatDate = (date: Date) => {
1321
return new Date(date).toLocaleDateString("en-US", {
@@ -17,6 +25,12 @@ const formatDate = (date: Date) => {
1725
});
1826
};
1927
28+
// Truncate description
29+
const truncateDescription = (text: string, maxLength: number = 100) => {
30+
if (text.length <= maxLength) return text;
31+
return text.slice(0, maxLength).trim() + "...";
32+
};
33+
2034
// Filter out current post and get 3 random posts
2135
const otherPosts = posts.filter((post) => post.slug !== currentSlug);
2236
const selectedPosts = otherPosts.sort(() => Math.random() - 0.5).slice(0, 3);
@@ -29,23 +43,27 @@ const selectedPosts = otherPosts.sort(() => Math.random() - 0.5).slice(0, 3);
2943
{
3044
selectedPosts.map((post) => (
3145
<article class="post-card">
32-
<h3 class="post-title">
33-
<a href={`/blog/${post.slug}`}>{post.data.title}</a>
34-
</h3>
35-
<div class="post-meta">
36-
<time datetime={post.data.publishDate.toISOString()}>
37-
{formatDate(post.data.publishDate)}
38-
</time>
39-
{post.data.author && <span class="post-author">by {post.data.author}</span>}
40-
</div>
41-
{post.data.companyName && (
42-
<p>
43-
<span class="case-study-label">Case Study</span>
44-
</p>
45-
)}
46-
<p class="post-description">{post.data.description}</p>
47-
<a href={`/blog/${post.slug}`} class="read-more">
48-
Read more →
46+
<a href={`/blog/${post.slug}`} class="post-card-link">
47+
<div class="post-image-wrapper">
48+
<img
49+
src={getPostImage(post)}
50+
alt={post.data.title}
51+
loading="lazy"
52+
class="post-image"
53+
/>
54+
{post.data.companyName && (
55+
<span class="card-badge-case-study">Case Study</span>
56+
)}
57+
</div>
58+
<div class="post-content">
59+
<h3 class="post-title">{post.data.title}</h3>
60+
<p class="post-description">{truncateDescription(post.data.description)}</p>
61+
<div class="post-meta">
62+
<time datetime={post.data.publishDate.toISOString()}>
63+
{formatDate(post.data.publishDate)}
64+
</time>
65+
</div>
66+
</div>
4967
</a>
5068
</article>
5169
))
@@ -67,109 +85,123 @@ const selectedPosts = otherPosts.sort(() => Math.random() - 0.5).slice(0, 3);
6785

6886
.section-title {
6987
margin: 0 0 2rem;
70-
font-size: calc(1rem * var(--font-scale-factor));
71-
font-weight: 400;
88+
font-size: calc(1.1rem * var(--font-scale-factor));
89+
font-weight: 500;
7290
color: var(--text-body-primary);
7391
text-align: left;
74-
padding-left: 20px;
7592
}
7693

7794
.posts-grid {
7895
display: grid;
79-
grid-template-columns: repeat(1, 1fr);
80-
gap: 25px;
96+
grid-template-columns: 1fr;
97+
gap: 24px;
8198

8299
@media (min-width: 640px) {
83100
grid-template-columns: repeat(2, 1fr);
84-
gap: 30px;
101+
gap: 28px;
85102
}
86103

87104
@media (min-width: 1024px) {
88105
grid-template-columns: repeat(3, 1fr);
89-
gap: 40px;
106+
gap: 32px;
90107
}
91108
}
92109

93110
.post-card {
94-
display: block;
95-
text-decoration: none;
96-
color: inherit;
97-
padding: 20px;
98-
background-color: #f9f9f9;
99-
border-width: 0 0 2px 0;
100-
border-style: solid;
101-
border-color: #f5f5f5;
102-
transition:
103-
transform 0.2s ease,
104-
box-shadow 0.2s ease,
105-
border-color 0.2s ease;
106-
transform: translateY(0);
107-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.03);
111+
background: white;
112+
border-radius: 10px;
113+
overflow: hidden;
114+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
115+
transition: transform 0.25s ease, box-shadow 0.25s ease;
108116

109117
&:hover {
110-
transform: translateY(-5px);
111-
border-color: var(--primary-button-bg, #0c8ce0);
112-
}
118+
transform: translateY(-6px);
119+
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
113120

114-
.post-title {
115-
margin: 0 0 15px 0;
116-
font-size: calc(1.5rem * var(--font-scale-factor));
117-
font-weight: 400;
118-
119-
a {
120-
color: var(--text-body-primary);
121-
text-decoration: none;
122-
&:hover {
123-
color: var(--primary-button-bg, #0c8ce0);
124-
}
121+
.post-image {
122+
transform: scale(1.05);
123+
}
124+
125+
.post-title {
126+
color: var(--primary-button-bg, #0c8ce0);
125127
}
126128
}
127129

128-
.post-meta {
129-
display: flex;
130-
flex-wrap: wrap;
131-
gap: 0.5rem;
132-
color: var(--text-body-secondary);
133-
margin-bottom: 8px;
134-
font-size: 14px;
135-
font-weight: 300;
130+
.post-card-link {
131+
display: block;
132+
text-decoration: none;
133+
color: inherit;
134+
}
136135

137-
.post-author {
138-
&::before {
139-
content: "•";
140-
margin-right: 0.5rem;
141-
}
142-
}
136+
.post-image-wrapper {
137+
position: relative;
138+
overflow: hidden;
139+
background: #f8f8f8;
143140
}
144141

145-
.post-description {
146-
margin: 1rem 0;
147-
line-height: 1.6;
148-
font-weight: 300;
149-
color: var(--text-body-primary);
150-
font-size: calc(1rem * var(--font-scale-factor));
142+
.post-image {
143+
width: 100%;
144+
height: auto;
145+
display: block;
146+
transition: transform 0.4s ease;
151147
}
152148

153-
.case-study-label {
154-
display: inline-block;
155-
color: var(--surface-main-primary);
149+
.card-badge-case-study {
150+
position: absolute;
151+
top: 12px;
152+
left: 12px;
153+
padding: 4px 10px;
154+
background: rgba(255, 255, 255, 0.95);
155+
color: #166534;
156156
font-size: 10px;
157-
font-weight: 400;
158-
padding: 5px 10px;
159-
margin-bottom: 0.5rem;
160-
border-radius: 50px;
161-
background-color: #f5f5f5;
162-
border: 1px solid var(--surface-main-primary);
157+
font-weight: 600;
158+
text-transform: uppercase;
159+
letter-spacing: 0.5px;
160+
border-radius: 4px;
161+
backdrop-filter: blur(4px);
162+
}
163+
164+
.post-content {
165+
padding: 1.25rem;
166+
}
167+
168+
.post-title {
169+
margin: 0 0 0.75rem;
170+
font-size: 1.1rem;
171+
font-weight: 500;
172+
line-height: 1.4;
173+
color: var(--text-body-primary);
174+
transition: color 0.2s ease;
175+
176+
// Clamp to 2 lines
177+
display: -webkit-box;
178+
-webkit-line-clamp: 2;
179+
-webkit-box-orient: vertical;
180+
overflow: hidden;
163181
}
164182

165-
.read-more {
166-
display: inline-block;
167-
color: var(--primary-text-color);
168-
font-size: 14px;
183+
.post-description {
184+
margin: 0 0 1rem;
185+
font-size: 0.9rem;
186+
line-height: 1.5;
187+
color: var(--text-body-secondary, #666);
169188
font-weight: 300;
170-
text-decoration: none;
171-
&:hover {
172-
text-decoration: underline;
189+
190+
// Clamp to 2 lines for more stories
191+
display: -webkit-box;
192+
-webkit-line-clamp: 2;
193+
-webkit-box-orient: vertical;
194+
overflow: hidden;
195+
}
196+
197+
.post-meta {
198+
display: flex;
199+
align-items: center;
200+
font-size: 12px;
201+
color: var(--text-body-secondary, #888);
202+
203+
time {
204+
font-weight: 400;
173205
}
174206
}
175207
}

src/content/blog/defguard-1.5-release-notes.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
---
22
title: Release 1.5 with Mobile apps, External SSO MFA, MFA with Biometry
33
publishDate: 2025-09-15
4-
description: This is the biggest, most feature packed release we have ever done! Weve introduced 11 major features and nearly 100 bugfixes.
4+
description: This is the biggest, most feature packed release we have ever done! We've introduced 11 major features and nearly 100 bugfixes.
55
draft: false
6+
image: "/images/blog/defguard-1.5-release-notes/15_release_1.png"
7+
tags: ["release", "mobile app", "mfa", "biometry", "sso", "wireguard", "ios", "android"]
68
---
79

810
import YouTubeVideo from "../../components/video/YouTubeVideo.astro";

src/content/blog/defguard-pre-seed.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ description: "Defguard has established strategic partnerships with top open-sour
55
author: "Michał Gryczka"
66

77
image: "/images/blog/defguard_founders_and_Hard2beat_partners.png"
8+
tags: ["news", "funding", "pre-seed", "startup", "venture capital", "partnership"]
89
---
910

1011
import YouTubeVideo from "../../components/video/YouTubeVideo.astro";

src/content/blog/defguard-release.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ description: "Defguard offers a unique combination of security-related functiona
55
author: "Robert Olejnik"
66

77
image: "/images/blog/defguard-main-screen.png"
8+
tags: ["release", "launch", "wireguard", "zero-trust", "mfa", "open source", "identity management"]
89
---
910

1011
### TL;DR

src/content/blog/fortitoken-alternative-vpn-mfa.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ description: "Stop paying the 'security tax.' Legacy VPNs like Fortinet treat MF
66
author: "Robert (Co-Founder, Defguard)"
77
image: "/images/blog/mfa-isnt-an-addon/mfa-hero.png"
88
draft: true
9+
tags: ["fortitoken", "mfa", "fortinet alternative", "security", "nis2", "vpn pricing"]
910
---
1011

1112
![Security shouldn't cost extra — MFA isn't an add-on](/images/blog/mfa-isnt-an-addon/mfa-hero.png)

src/content/blog/mfa-wireguard-nis2-compliance.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ publishDate: 2025-10-07
44
description: "The NIS2 Directive mandates MFA for VPNs. Learn how to implement true, connection-level Multi-Factor Authentication for VPNs using the WireGuard® protocol with Defguard to ensure compliance and top-tier security."
55
author: "Piotr Borkowicz"
66
image: "/images/blog/Defguard-nis2-mfa/wireguard-nis2-hero.png"
7+
tags: ["mfa", "wireguard", "nis2", "compliance", "2fa", "security", "enterprise"]
78
---
89

910
import MfaDiagram from '../../components/MfaDiagram.astro';

src/content/blog/prusa-vpn-scaling-with-defguard.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ companySegment: "Desktop and industrial 3D printing"
1010
companyWebsite: "https://www.prusa3d.com"
1111

1212
image: "/images/blog/prusa.png"
13+
tags: ["prusa", "enterprise vpn", "self-hosted", "wireguard", "mfa", "identity management"]
1314
---
1415

1516
![How Prusa Secured Global VPN Access with Defguard](/images/blog/prusa.png)

src/content/blog/self-hosted-vpn-private-cloud-acquinox-defguard.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ companySegment: "Private Equity"
1010
companyWebsite: "https://acquinox.capital"
1111

1212
image: "/images/blog/acquinox.png"
13+
tags: ["private cloud", "self-hosted", "data sovereignty", "sso", "finance", "gdpr"]
1314
---
1415

1516
![Private Equity firm builds secure private cloud with Defguard](/images/blog/acquinox.png)

src/content/blog/ssl-vpn-performance-protocol-problem.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ description: "Tired of users complaining your Fortinet VPN is slow? You're not a
55
author: "Piotr Borkowicz"
66
publishDate: 2025-11-12
77
image: "/images/blog/SSLVPN/SSL-VPN.png"
8+
tags: ["ssl vpn", "fortinet", "vpn performance", "wireguard", "migration", "enterprise vpn"]
89
---
910

1011
![Understanding SSL VPN Limitations: Transport, Mobility and Modern Alternatives](/images/blog/SSLVPN/SSL-VPN.png)

src/content/blog/why-open-source.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
title: "Why We Made Defguard Open Source"
33
publishDate: 2025-05-23
4-
description: "Discover how new Swiss laws are reshaping digital sovereignty — and why Defguards open source model is leading the way in secure, transparent infrastructure."
4+
description: "Discover how new Swiss laws are reshaping digital sovereignty — and why Defguard's open source model is leading the way in secure, transparent infrastructure."
55
author: "Michał Gryczka"
66

77
image: "/images/blog/swiss-dg.png"
8+
tags: ["open source", "digital sovereignty", "transparency", "swiss law", "embag", "security"]
89
---
910

1011
![](/images/blog/swiss-dg.png)

0 commit comments

Comments
 (0)