@xenterprises/nuxt-x-marketing 1.0.0 → 1.0.1
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/.playground/pages/blog/detail.vue +341 -249
- package/.playground/pages/notifications/social-proof-toast.vue +330 -70
- package/app/assets/css/x-marketing.css +1 -0
- package/app/components/X/Mark/Blog/Detail.vue +169 -222
- package/app/components/X/Mark/CodeBlock/index.vue +69 -0
- package/app/components/X/Mark/SocialProof/Toast.vue +61 -16
- package/nuxt.config.ts +12 -3
- package/package.json +4 -2
- package/.claude/settings.local.json +0 -22
- package/.playground/package-lock.json +0 -6
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="min-h-screen">
|
|
3
3
|
<!-- Page Header -->
|
|
4
|
-
<div
|
|
5
|
-
|
|
4
|
+
<div
|
|
5
|
+
class="bg-white dark:bg-neutral-900 border-b border-neutral-200 dark:border-neutral-800 px-8 py-6"
|
|
6
|
+
>
|
|
7
|
+
<h1 class="text-2xl font-bold text-neutral-900 dark:text-white">
|
|
8
|
+
Blog Detail
|
|
9
|
+
</h1>
|
|
6
10
|
<p class="mt-2 text-neutral-600 dark:text-neutral-400">
|
|
7
11
|
Full blog post view with sidebar, rich content, and navigation.
|
|
8
12
|
</p>
|
|
@@ -17,134 +21,146 @@
|
|
|
17
21
|
:toc="tableOfContents"
|
|
18
22
|
>
|
|
19
23
|
<template #default>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
</
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
24
|
+
<article class="prose dark:prose-invert max-w-none">
|
|
25
|
+
<p class="lead">
|
|
26
|
+
Building a marketing website has never been easier. With modern
|
|
27
|
+
tools like Nuxt, Vue, and Tailwind CSS, developers can create
|
|
28
|
+
stunning, performant sites in record time. This guide walks you
|
|
29
|
+
through the essential patterns and best practices for crafting
|
|
30
|
+
marketing sites that convert.
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
<h2 id="getting-started">Getting Started</h2>
|
|
34
|
+
<p>
|
|
35
|
+
Before diving into the code, it's important to understand the core
|
|
36
|
+
principles that make marketing websites effective. These include
|
|
37
|
+
clear messaging, compelling visuals, and optimized performance.
|
|
38
|
+
</p>
|
|
39
|
+
<p>
|
|
40
|
+
The nuxt-x-marketing layer provides 33 production-ready components
|
|
41
|
+
specifically designed for marketing sites. From hero sections to
|
|
42
|
+
testimonials, each component is crafted with conversion in mind.
|
|
43
|
+
</p>
|
|
44
|
+
|
|
45
|
+
<h2 id="project-setup">Project Setup</h2>
|
|
46
|
+
<p>
|
|
47
|
+
Start by creating a new Nuxt project and adding the marketing
|
|
48
|
+
layer:
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
<XMarkCodeBlock :code="bashCode" language="bash" show-copy />
|
|
52
|
+
|
|
53
|
+
<p>Then configure your <code>nuxt.config.ts</code>:</p>
|
|
54
|
+
|
|
55
|
+
<XMarkCodeBlock
|
|
56
|
+
:code="nuxtConfigCode"
|
|
57
|
+
language="typescript"
|
|
58
|
+
show-copy
|
|
59
|
+
/>
|
|
60
|
+
|
|
61
|
+
<h2 id="hero-sections">Creating Hero Sections</h2>
|
|
62
|
+
<p>
|
|
63
|
+
The hero section is the first thing visitors see. It needs to
|
|
64
|
+
capture attention immediately and communicate your value
|
|
65
|
+
proposition clearly.
|
|
66
|
+
</p>
|
|
67
|
+
|
|
68
|
+
<figure>
|
|
69
|
+
<img
|
|
70
|
+
src="https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=800&h=400&fit=crop"
|
|
71
|
+
alt="Dashboard design"
|
|
72
|
+
/>
|
|
73
|
+
<figcaption>
|
|
74
|
+
A well-designed hero section can increase conversions by up to
|
|
75
|
+
35%.
|
|
76
|
+
</figcaption>
|
|
77
|
+
</figure>
|
|
78
|
+
|
|
79
|
+
<p>Key elements of an effective hero section:</p>
|
|
80
|
+
<ul>
|
|
81
|
+
<li>
|
|
82
|
+
<strong>Clear headline</strong> — Communicate your main value
|
|
83
|
+
proposition in under 10 words
|
|
84
|
+
</li>
|
|
85
|
+
<li>
|
|
86
|
+
<strong>Supporting text</strong> — Expand on the headline with
|
|
87
|
+
1-2 sentences
|
|
88
|
+
</li>
|
|
89
|
+
<li>
|
|
90
|
+
<strong>Strong CTA</strong> — Use action-oriented button text
|
|
91
|
+
</li>
|
|
92
|
+
<li>
|
|
93
|
+
<strong>Visual element</strong> — High-quality image or video
|
|
94
|
+
that reinforces the message
|
|
95
|
+
</li>
|
|
96
|
+
</ul>
|
|
97
|
+
|
|
98
|
+
<h2 id="social-proof">Adding Social Proof</h2>
|
|
99
|
+
<p>
|
|
100
|
+
Social proof is one of the most powerful conversion tools.
|
|
101
|
+
Testimonials, logos, and trust badges help establish credibility.
|
|
102
|
+
</p>
|
|
103
|
+
|
|
104
|
+
<blockquote>
|
|
105
|
+
"These components saved us weeks of development time. The quality
|
|
106
|
+
and attention to detail is outstanding."
|
|
107
|
+
<cite>— Sarah Chen, CTO at TechCorp</cite>
|
|
108
|
+
</blockquote>
|
|
109
|
+
|
|
110
|
+
<p>
|
|
111
|
+
Use the testimonials component to showcase customer feedback. The
|
|
112
|
+
grid layout works well for displaying multiple testimonials, while
|
|
113
|
+
the featured layout highlights a single powerful quote.
|
|
114
|
+
</p>
|
|
115
|
+
|
|
116
|
+
<h2 id="pricing-tables">Pricing Tables</h2>
|
|
117
|
+
<p>
|
|
118
|
+
Your pricing page is where conversions happen. Make it easy for
|
|
119
|
+
visitors to understand their options and choose the right plan.
|
|
120
|
+
</p>
|
|
121
|
+
|
|
122
|
+
<h3>Best Practices</h3>
|
|
123
|
+
<ol>
|
|
124
|
+
<li>Limit to 3-4 pricing tiers to avoid decision paralysis</li>
|
|
125
|
+
<li>Highlight the most popular or recommended plan</li>
|
|
126
|
+
<li>Use clear feature comparisons</li>
|
|
127
|
+
<li>Include trust badges near the pricing</li>
|
|
128
|
+
<li>Offer a money-back guarantee to reduce friction</li>
|
|
129
|
+
</ol>
|
|
130
|
+
|
|
131
|
+
<h2 id="performance">Performance Optimization</h2>
|
|
132
|
+
<p>
|
|
133
|
+
Performance directly impacts conversions. Studies show that a
|
|
134
|
+
<mark>1-second delay</mark> in page load time can result in a
|
|
135
|
+
<strong>7% reduction</strong> in conversions.
|
|
136
|
+
</p>
|
|
137
|
+
|
|
138
|
+
<p>The marketing layer includes built-in optimizations:</p>
|
|
139
|
+
|
|
140
|
+
<div class="not-prose">
|
|
141
|
+
<UTable
|
|
142
|
+
:data="performanceData"
|
|
143
|
+
:columns="performanceColumns"
|
|
144
|
+
class="flex-1"
|
|
145
|
+
/>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<hr />
|
|
149
|
+
|
|
150
|
+
<h2 id="conclusion">Conclusion</h2>
|
|
151
|
+
<p>
|
|
152
|
+
Building effective marketing websites requires the right
|
|
153
|
+
combination of design, performance, and conversion optimization.
|
|
154
|
+
With nuxt-x-marketing, you get battle-tested components that
|
|
155
|
+
handle the heavy lifting, letting you focus on your content and
|
|
156
|
+
messaging.
|
|
157
|
+
</p>
|
|
158
|
+
<p>
|
|
159
|
+
Ready to get started? Check out the
|
|
160
|
+
<a href="/content/features">features documentation</a> or browse
|
|
161
|
+
the <a href="/">component library</a> to see what's available.
|
|
162
|
+
</p>
|
|
163
|
+
</article>
|
|
148
164
|
</template>
|
|
149
165
|
|
|
150
166
|
<!-- Custom Sidebar Content -->
|
|
@@ -164,70 +180,21 @@ npm install @xenterprises/nuxt-x-marketing</code></pre>
|
|
|
164
180
|
<div class="border-t border-neutral-200 dark:border-neutral-800">
|
|
165
181
|
<div class="max-w-4xl mx-auto px-8 py-12">
|
|
166
182
|
<h2 class="text-lg font-semibold mb-6">Blog Detail Props</h2>
|
|
167
|
-
<div class="
|
|
168
|
-
<
|
|
169
|
-
<thead>
|
|
170
|
-
<tr class="border-b border-neutral-200 dark:border-neutral-700">
|
|
171
|
-
<th class="text-left py-3 px-4 font-medium">Prop</th>
|
|
172
|
-
<th class="text-left py-3 px-4 font-medium">Type</th>
|
|
173
|
-
<th class="text-left py-3 px-4 font-medium">Default</th>
|
|
174
|
-
<th class="text-left py-3 px-4 font-medium">Description</th>
|
|
175
|
-
</tr>
|
|
176
|
-
</thead>
|
|
177
|
-
<tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
|
|
178
|
-
<tr>
|
|
179
|
-
<td class="py-3 px-4 font-mono text-xs">post</td>
|
|
180
|
-
<td class="py-3 px-4">Object</td>
|
|
181
|
-
<td class="py-3 px-4">required</td>
|
|
182
|
-
<td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Post object with title, img: { src, alt? }, date, author, etc.</td>
|
|
183
|
-
</tr>
|
|
184
|
-
<tr>
|
|
185
|
-
<td class="py-3 px-4 font-mono text-xs">previousPost</td>
|
|
186
|
-
<td class="py-3 px-4">Object</td>
|
|
187
|
-
<td class="py-3 px-4">null</td>
|
|
188
|
-
<td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Previous post for navigation</td>
|
|
189
|
-
</tr>
|
|
190
|
-
<tr>
|
|
191
|
-
<td class="py-3 px-4 font-mono text-xs">nextPost</td>
|
|
192
|
-
<td class="py-3 px-4">Object</td>
|
|
193
|
-
<td class="py-3 px-4">null</td>
|
|
194
|
-
<td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Next post for navigation</td>
|
|
195
|
-
</tr>
|
|
196
|
-
<tr>
|
|
197
|
-
<td class="py-3 px-4 font-mono text-xs">toc</td>
|
|
198
|
-
<td class="py-3 px-4">Array</td>
|
|
199
|
-
<td class="py-3 px-4">[]</td>
|
|
200
|
-
<td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Table of contents [{ id, text, depth }]</td>
|
|
201
|
-
</tr>
|
|
202
|
-
</tbody>
|
|
203
|
-
</table>
|
|
183
|
+
<div class="not-prose">
|
|
184
|
+
<UTable :data="propsData" :columns="propsColumns" class="flex-1" />
|
|
204
185
|
</div>
|
|
205
186
|
|
|
206
187
|
<h2 class="text-lg font-semibold mt-12 mb-6">Slots</h2>
|
|
207
|
-
<div class="
|
|
208
|
-
<
|
|
209
|
-
<thead>
|
|
210
|
-
<tr class="border-b border-neutral-200 dark:border-neutral-700">
|
|
211
|
-
<th class="text-left py-3 px-4 font-medium">Slot</th>
|
|
212
|
-
<th class="text-left py-3 px-4 font-medium">Description</th>
|
|
213
|
-
</tr>
|
|
214
|
-
</thead>
|
|
215
|
-
<tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
|
|
216
|
-
<tr>
|
|
217
|
-
<td class="py-3 px-4 font-mono text-xs">default</td>
|
|
218
|
-
<td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Main article content (prose)</td>
|
|
219
|
-
</tr>
|
|
220
|
-
<tr>
|
|
221
|
-
<td class="py-3 px-4 font-mono text-xs">sidebar</td>
|
|
222
|
-
<td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Custom sidebar content (overrides default)</td>
|
|
223
|
-
</tr>
|
|
224
|
-
</tbody>
|
|
225
|
-
</table>
|
|
188
|
+
<div class="not-prose">
|
|
189
|
+
<UTable :data="slotsData" :columns="slotsColumns" class="flex-1" />
|
|
226
190
|
</div>
|
|
227
191
|
|
|
228
192
|
<h2 class="text-lg font-semibold mt-12 mb-6">Post Object Structure</h2>
|
|
229
|
-
<div
|
|
230
|
-
|
|
193
|
+
<div
|
|
194
|
+
class="bg-neutral-100 dark:bg-neutral-800 rounded-lg p-4 text-sm font-mono overflow-x-auto"
|
|
195
|
+
>
|
|
196
|
+
<pre>
|
|
197
|
+
{
|
|
231
198
|
title: "Post Title",
|
|
232
199
|
excerpt: "Brief description...",
|
|
233
200
|
img: { src: "https://...", alt: "Image description" },
|
|
@@ -240,7 +207,8 @@ npm install @xenterprises/nuxt-x-marketing</code></pre>
|
|
|
240
207
|
bio: "Author bio...",
|
|
241
208
|
twitter: "@handle"
|
|
242
209
|
}
|
|
243
|
-
}</pre
|
|
210
|
+
}</pre
|
|
211
|
+
>
|
|
244
212
|
</div>
|
|
245
213
|
|
|
246
214
|
<h2 class="text-lg font-semibold mt-12 mb-4">Code Example</h2>
|
|
@@ -251,6 +219,31 @@ npm install @xenterprises/nuxt-x-marketing</code></pre>
|
|
|
251
219
|
</template>
|
|
252
220
|
|
|
253
221
|
<script setup>
|
|
222
|
+
import { h, resolveComponent } from "vue";
|
|
223
|
+
|
|
224
|
+
// Code examples for Shiki highlighting
|
|
225
|
+
const bashCode = `# Create new project
|
|
226
|
+
npx nuxi init my-marketing-site
|
|
227
|
+
cd my-marketing-site
|
|
228
|
+
|
|
229
|
+
# Install dependencies
|
|
230
|
+
npm install
|
|
231
|
+
|
|
232
|
+
# Add the marketing layer
|
|
233
|
+
npm install @xenterprises/nuxt-x-marketing`;
|
|
234
|
+
|
|
235
|
+
const nuxtConfigCode = `export default defineNuxtConfig({
|
|
236
|
+
extends: ['@xenterprises/nuxt-x-marketing'],
|
|
237
|
+
|
|
238
|
+
modules: ['@nuxt/ui'],
|
|
239
|
+
|
|
240
|
+
app: {
|
|
241
|
+
head: {
|
|
242
|
+
title: 'My Marketing Site'
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
})`;
|
|
246
|
+
|
|
254
247
|
const codeExample = `<!-- With Nuxt Content v3 -->
|
|
255
248
|
<script setup>
|
|
256
249
|
const route = useRoute()
|
|
@@ -284,96 +277,195 @@ const { data: surround } = await useAsyncData('surround', () =>
|
|
|
284
277
|
/>
|
|
285
278
|
</template>
|
|
286
279
|
</XMarkBlogDetail>
|
|
287
|
-
</template
|
|
280
|
+
</template>`;
|
|
281
|
+
|
|
282
|
+
// Performance table data
|
|
283
|
+
const performanceData = ref([
|
|
284
|
+
{ feature: "Lazy loading", benefit: "Images load only when visible" },
|
|
285
|
+
{ feature: "CSS purging", benefit: "Only used styles are shipped" },
|
|
286
|
+
{ feature: "Component splitting", benefit: "Components load on demand" },
|
|
287
|
+
{ feature: "Font optimization", benefit: "Fonts preloaded and subset" },
|
|
288
|
+
]);
|
|
289
|
+
|
|
290
|
+
const performanceColumns = [
|
|
291
|
+
{
|
|
292
|
+
accessorKey: "feature",
|
|
293
|
+
header: "Feature",
|
|
294
|
+
cell: ({ row }) => row.getValue("feature"),
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
accessorKey: "benefit",
|
|
298
|
+
header: "Benefit",
|
|
299
|
+
cell: ({ row }) => row.getValue("benefit"),
|
|
300
|
+
},
|
|
301
|
+
];
|
|
302
|
+
|
|
303
|
+
// Props documentation table data
|
|
304
|
+
const propsData = ref([
|
|
305
|
+
{
|
|
306
|
+
prop: "post",
|
|
307
|
+
type: "Object",
|
|
308
|
+
default: "required",
|
|
309
|
+
description:
|
|
310
|
+
"Post object with title, img: { src, alt? }, date, author, etc.",
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
prop: "previousPost",
|
|
314
|
+
type: "Object",
|
|
315
|
+
default: "null",
|
|
316
|
+
description: "Previous post for navigation",
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
prop: "nextPost",
|
|
320
|
+
type: "Object",
|
|
321
|
+
default: "null",
|
|
322
|
+
description: "Next post for navigation",
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
prop: "toc",
|
|
326
|
+
type: "Array",
|
|
327
|
+
default: "[]",
|
|
328
|
+
description: "Table of contents [{ id, text, depth }]",
|
|
329
|
+
},
|
|
330
|
+
]);
|
|
331
|
+
|
|
332
|
+
const propsColumns = [
|
|
333
|
+
{
|
|
334
|
+
accessorKey: "prop",
|
|
335
|
+
header: "Prop",
|
|
336
|
+
cell: ({ row }) =>
|
|
337
|
+
h("code", { class: "text-xs font-mono" }, row.getValue("prop")),
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
accessorKey: "type",
|
|
341
|
+
header: "Type",
|
|
342
|
+
cell: ({ row }) => row.getValue("type"),
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
accessorKey: "default",
|
|
346
|
+
header: "Default",
|
|
347
|
+
cell: ({ row }) => row.getValue("default"),
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
accessorKey: "description",
|
|
351
|
+
header: "Description",
|
|
352
|
+
cell: ({ row }) => row.getValue("description"),
|
|
353
|
+
},
|
|
354
|
+
];
|
|
355
|
+
|
|
356
|
+
// Slots table data
|
|
357
|
+
const slotsData = ref([
|
|
358
|
+
{ slot: "default", description: "Main article content (prose)" },
|
|
359
|
+
{
|
|
360
|
+
slot: "sidebar",
|
|
361
|
+
description: "Custom sidebar content (overrides default)",
|
|
362
|
+
},
|
|
363
|
+
]);
|
|
364
|
+
|
|
365
|
+
const slotsColumns = [
|
|
366
|
+
{
|
|
367
|
+
accessorKey: "slot",
|
|
368
|
+
header: "Slot",
|
|
369
|
+
cell: ({ row }) =>
|
|
370
|
+
h("code", { class: "text-xs font-mono" }, row.getValue("slot")),
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
accessorKey: "description",
|
|
374
|
+
header: "Description",
|
|
375
|
+
cell: ({ row }) => row.getValue("description"),
|
|
376
|
+
},
|
|
377
|
+
];
|
|
288
378
|
|
|
289
379
|
// Main post
|
|
290
380
|
const post = {
|
|
291
|
-
title:
|
|
292
|
-
excerpt:
|
|
381
|
+
title: "Building Modern Marketing Sites with Nuxt",
|
|
382
|
+
excerpt:
|
|
383
|
+
"A comprehensive guide to creating beautiful, performant marketing websites using Vue, Nuxt, and modern web technologies.",
|
|
293
384
|
img: {
|
|
294
|
-
src:
|
|
295
|
-
alt:
|
|
385
|
+
src: "https://images.unsplash.com/photo-1519389950473-47ba0277781c?w=1200&h=600&fit=crop",
|
|
386
|
+
alt: "Team working on laptops",
|
|
296
387
|
},
|
|
297
|
-
date:
|
|
298
|
-
readingTime:
|
|
299
|
-
category:
|
|
388
|
+
date: "2024-01-15",
|
|
389
|
+
readingTime: "8 min read",
|
|
390
|
+
category: "Tutorial",
|
|
300
391
|
author: {
|
|
301
|
-
name:
|
|
302
|
-
avatar:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
392
|
+
name: "Sarah Chen",
|
|
393
|
+
avatar:
|
|
394
|
+
"https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop",
|
|
395
|
+
bio: "Sarah is a frontend developer specializing in Vue and Nuxt. She writes about web development and design systems.",
|
|
396
|
+
twitter: "@sarahchen",
|
|
397
|
+
},
|
|
398
|
+
};
|
|
307
399
|
|
|
308
400
|
// Navigation posts
|
|
309
401
|
const previousPost = {
|
|
310
|
-
title:
|
|
311
|
-
slug:
|
|
312
|
-
}
|
|
402
|
+
title: "Introduction to Vue 3 Composition API",
|
|
403
|
+
slug: "vue-composition-api",
|
|
404
|
+
};
|
|
313
405
|
|
|
314
406
|
const nextPost = {
|
|
315
|
-
title:
|
|
316
|
-
slug:
|
|
317
|
-
}
|
|
407
|
+
title: "Optimizing Nuxt for Production",
|
|
408
|
+
slug: "nuxt-production-optimization",
|
|
409
|
+
};
|
|
318
410
|
|
|
319
411
|
// Table of contents
|
|
320
412
|
const tableOfContents = [
|
|
321
|
-
{ id:
|
|
322
|
-
{ id:
|
|
323
|
-
{ id:
|
|
324
|
-
{ id:
|
|
325
|
-
{ id:
|
|
326
|
-
{ id:
|
|
327
|
-
{ id:
|
|
328
|
-
]
|
|
413
|
+
{ id: "getting-started", text: "Getting Started", depth: 2 },
|
|
414
|
+
{ id: "project-setup", text: "Project Setup", depth: 2 },
|
|
415
|
+
{ id: "hero-sections", text: "Creating Hero Sections", depth: 2 },
|
|
416
|
+
{ id: "social-proof", text: "Adding Social Proof", depth: 2 },
|
|
417
|
+
{ id: "pricing-tables", text: "Pricing Tables", depth: 2 },
|
|
418
|
+
{ id: "performance", text: "Performance Optimization", depth: 2 },
|
|
419
|
+
{ id: "conclusion", text: "Conclusion", depth: 2 },
|
|
420
|
+
];
|
|
329
421
|
|
|
330
422
|
// Sidebar data
|
|
331
423
|
const categories = [
|
|
332
|
-
{ name:
|
|
333
|
-
{ name:
|
|
334
|
-
{ name:
|
|
335
|
-
{ name:
|
|
336
|
-
{ name:
|
|
337
|
-
]
|
|
424
|
+
{ name: "Tutorial", slug: "tutorial", count: 12 },
|
|
425
|
+
{ name: "Guide", slug: "guide", count: 8 },
|
|
426
|
+
{ name: "Design", slug: "design", count: 6 },
|
|
427
|
+
{ name: "Performance", slug: "performance", count: 4 },
|
|
428
|
+
{ name: "News", slug: "news", count: 3 },
|
|
429
|
+
];
|
|
338
430
|
|
|
339
431
|
const tags = [
|
|
340
|
-
{ name:
|
|
341
|
-
{ name:
|
|
342
|
-
{ name:
|
|
343
|
-
{ name:
|
|
344
|
-
{ name:
|
|
345
|
-
{ name:
|
|
346
|
-
{ name:
|
|
347
|
-
{ name:
|
|
348
|
-
]
|
|
432
|
+
{ name: "Nuxt", slug: "nuxt" },
|
|
433
|
+
{ name: "Vue", slug: "vue" },
|
|
434
|
+
{ name: "Tailwind CSS", slug: "tailwind" },
|
|
435
|
+
{ name: "Components", slug: "components" },
|
|
436
|
+
{ name: "Marketing", slug: "marketing" },
|
|
437
|
+
{ name: "SEO", slug: "seo" },
|
|
438
|
+
{ name: "Performance", slug: "performance" },
|
|
439
|
+
{ name: "Design", slug: "design" },
|
|
440
|
+
];
|
|
349
441
|
|
|
350
442
|
const recentPosts = [
|
|
351
443
|
{
|
|
352
|
-
title:
|
|
353
|
-
slug:
|
|
444
|
+
title: "Dark Mode Best Practices",
|
|
445
|
+
slug: "dark-mode",
|
|
354
446
|
img: {
|
|
355
|
-
src:
|
|
356
|
-
alt:
|
|
447
|
+
src: "https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=200&h=200&fit=crop",
|
|
448
|
+
alt: "Dark mode",
|
|
357
449
|
},
|
|
358
|
-
date:
|
|
450
|
+
date: "2024-01-10",
|
|
359
451
|
},
|
|
360
452
|
{
|
|
361
|
-
title:
|
|
362
|
-
slug:
|
|
453
|
+
title: "Building a Landing Page in 10 Minutes",
|
|
454
|
+
slug: "landing-page-tutorial",
|
|
363
455
|
img: {
|
|
364
|
-
src:
|
|
365
|
-
alt:
|
|
456
|
+
src: "https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=200&h=200&fit=crop",
|
|
457
|
+
alt: "Landing page",
|
|
366
458
|
},
|
|
367
|
-
date:
|
|
459
|
+
date: "2024-01-05",
|
|
368
460
|
},
|
|
369
461
|
{
|
|
370
|
-
title:
|
|
371
|
-
slug:
|
|
462
|
+
title: "CSS Grid vs Flexbox: When to Use Each",
|
|
463
|
+
slug: "css-grid-flexbox",
|
|
372
464
|
img: {
|
|
373
|
-
src:
|
|
374
|
-
alt:
|
|
465
|
+
src: "https://images.unsplash.com/photo-1517694712202-14dd9538aa97?w=200&h=200&fit=crop",
|
|
466
|
+
alt: "CSS layout",
|
|
375
467
|
},
|
|
376
|
-
date:
|
|
377
|
-
}
|
|
378
|
-
]
|
|
468
|
+
date: "2024-01-02",
|
|
469
|
+
},
|
|
470
|
+
];
|
|
379
471
|
</script>
|