create-lacspace-app 1.0.0 → 1.2.0

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.
Files changed (3) hide show
  1. package/README.md +14 -4
  2. package/dist/index.js +269 -7
  3. package/package.json +44 -10
package/README.md CHANGED
@@ -29,14 +29,24 @@ It asks for a project name and a template, scaffolds the project, installs depen
29
29
  | **business** | A professional company / agency site with services + CTA |
30
30
  | **ecommerce** | A modern storefront home with a featured product grid |
31
31
  | **saas** | A high-converting SaaS landing page with features + pricing |
32
+ | **blog** | An editorial blog / magazine home with a featured post + grid |
33
+ | **docs** | A documentation landing with quick-start + feature cards |
34
+ | **dashboard** | An admin app shell with a sidebar, stat cards and activity |
35
+ | **restaurant** | A warm restaurant / cafe site with a menu and reservations |
32
36
 
33
37
  Every template is a real Next.js 15 App Router + Tailwind v4 project — dark, modern, responsive, with a gradient accent you can theme.
34
38
 
35
- ## Batteries already wired
39
+ ## A complete, polished project — not a blank page
36
40
 
37
- - **`lib/site.ts`** one [`@lacspace/seo`](https://www.npmjs.com/package/@lacspace/seo) `defineSite()` config drives your `<title>`, canonical, Open Graph, Twitter card and JSON-LD
38
- - **`next.config.mjs`** — hardened security headers via [`@lacspace/headers`](https://www.npmjs.com/package/@lacspace/headers)
39
- - **`app/robots.txt` + `app/sitemap.xml`**generated from your site config with [`@lacspace/robots`](https://www.npmjs.com/package/@lacspace/robots) & [`@lacspace/sitemap`](https://www.npmjs.com/package/@lacspace/sitemap)
41
+ Every generated app arrives finished, with the boring-but-essential things done:
42
+
43
+ - 🎨 **Beautiful home page** Tailwind v4, the Inter font, dark theme + a gradient accent
44
+ - 🔎 **SEO** — one [`@lacspace/seo`](https://www.npmjs.com/package/@lacspace/seo) `defineSite()` config drives your `<title>`, canonical, Open Graph, Twitter card and JSON-LD
45
+ - ✨ **Dynamic OG images** — every page auto-generates a social-share card at `/og` (no design tool)
46
+ - 🛡️ **Security headers** — HSTS, CSP, X-Frame-Options and more via [`@lacspace/headers`](https://www.npmjs.com/package/@lacspace/headers)
47
+ - 🗺️ **robots.txt + sitemap.xml** — generated from your config with [`@lacspace/robots`](https://www.npmjs.com/package/@lacspace/robots) & [`@lacspace/sitemap`](https://www.npmjs.com/package/@lacspace/sitemap)
48
+ - 🧩 **A styled 404, a PWA manifest, and `.env.example`** — the finishing touches most starters skip
49
+ - 🎁 **A `WELCOME.md`** that walks you through everything and shows the bonus packages you can drop in
40
50
 
41
51
  Edit `lib/site.ts` and `app/page.tsx` and you're off.
42
52
 
package/dist/index.js CHANGED
@@ -20,7 +20,11 @@ var TEMPLATES = [
20
20
  { key: "personal", label: "Personal portfolio", description: "A sleek personal / developer portfolio with projects and contact.", accent: ["#6366f1", "#a855f7"], siteName: "Your Name", siteDescription: "Developer, designer & maker. Selected work and writing." },
21
21
  { key: "business", label: "Business site", description: "A professional company / agency site with services and a CTA.", accent: ["#2563eb", "#06b6d4"], siteName: "Acme Studio", siteDescription: "We design and build digital products that grow businesses." },
22
22
  { key: "ecommerce", label: "E-commerce storefront", description: "A modern product storefront home with a featured grid.", accent: ["#0d9488", "#84cc16"], siteName: "Acme Store", siteDescription: "Beautiful things, thoughtfully made. Free shipping worldwide." },
23
- { key: "saas", label: "SaaS landing", description: "A high-converting SaaS landing page with features and pricing.", accent: ["#7c3aed", "#ec4899"], siteName: "Acme Cloud", siteDescription: "The all-in-one platform your team will love. Ship faster." }
23
+ { key: "saas", label: "SaaS landing", description: "A high-converting SaaS landing page with features and pricing.", accent: ["#7c3aed", "#ec4899"], siteName: "Acme Cloud", siteDescription: "The all-in-one platform your team will love. Ship faster." },
24
+ { key: "blog", label: "Blog / magazine", description: "A clean editorial blog home with a featured post and a grid.", accent: ["#f97316", "#ef4444"], siteName: "The Journal", siteDescription: "Essays, notes and stories on building things that matter." },
25
+ { key: "docs", label: "Documentation", description: "A docs landing with quick-start and feature cards.", accent: ["#0ea5e9", "#6366f1"], siteName: "Acme Docs", siteDescription: "Everything you need to build with Acme \u2014 guides, API and examples." },
26
+ { key: "dashboard", label: "Admin dashboard", description: "An app dashboard shell with stat cards and a table.", accent: ["#10b981", "#14b8a6"], siteName: "Acme Admin", siteDescription: "Your control center \u2014 metrics, activity and management in one place." },
27
+ { key: "restaurant", label: "Restaurant / cafe", description: "A warm restaurant home with menu highlights and reservations.", accent: ["#e11d48", "#f59e0b"], siteName: "Olive & Ember", siteDescription: "Seasonal plates, natural wine and a warm room. Book a table." }
24
28
  ];
25
29
  var pkgJson = (ctx) => JSON.stringify({
26
30
  name: ctx.name,
@@ -96,38 +100,59 @@ var globalsCss = (ctx) => `@import "tailwindcss";
96
100
  :root {
97
101
  --accent-from: ${ctx.template.accent[0]};
98
102
  --accent-to: ${ctx.template.accent[1]};
103
+ --bg: #0a0a0f;
104
+ --fg: #e5e7eb;
99
105
  }
100
106
 
107
+ * { border-color: rgb(255 255 255 / 0.08); }
101
108
  html { scroll-behavior: smooth; }
102
- body { background: #0a0a0f; color: #e5e7eb; -webkit-font-smoothing: antialiased; }
109
+ body {
110
+ background: var(--bg);
111
+ color: var(--fg);
112
+ -webkit-font-smoothing: antialiased;
113
+ text-rendering: optimizeLegibility;
114
+ }
115
+
116
+ ::selection { background: var(--accent-to); color: #0a0a0f; }
117
+ ::-webkit-scrollbar { width: 10px; height: 10px; }
118
+ ::-webkit-scrollbar-thumb { background: rgb(255 255 255 / 0.12); border-radius: 8px; }
119
+ :focus-visible { outline: 2px solid var(--accent-to); outline-offset: 2px; border-radius: 4px; }
103
120
 
104
121
  .gradient-text {
105
122
  background: linear-gradient(120deg, var(--accent-from), var(--accent-to));
106
123
  -webkit-background-clip: text; background-clip: text; color: transparent;
107
124
  }
108
125
  .gradient-bg { background: linear-gradient(120deg, var(--accent-from), var(--accent-to)); }
126
+
127
+ /* soft entrance for content */
128
+ @keyframes rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
129
+ main > section, main > * { animation: rise 0.6s cubic-bezier(0.22, 1, 0.36, 1) both; }
130
+ @media (prefers-reduced-motion: reduce) { *, ::before, ::after { animation: none !important; scroll-behavior: auto; } }
109
131
  `;
110
132
  var siteTs = (ctx) => `import { defineSite } from "@lacspace/seo";
111
133
 
112
134
  /** Your site's SEO configuration \u2014 set once, used everywhere. */
113
135
  export const site = defineSite({
114
136
  name: ${JSON.stringify(ctx.template.siteName)},
115
- url: "https://example.com",
137
+ url: process.env.NEXT_PUBLIC_SITE_URL ?? "https://example.com",
116
138
  description: ${JSON.stringify(ctx.template.siteDescription)},
117
139
  // twitter: "yourhandle",
118
- // ogImage: "/og",
140
+ ogImage: "/og", // \u2728 auto social-share images \u2014 see app/og/route.tsx
119
141
  });
120
142
  `;
121
143
  var layout = (ctx) => `import type { Metadata } from "next";
144
+ import { Inter } from "next/font/google";
122
145
  import { site } from "@/lib/site";
123
146
  import "./globals.css";
124
147
 
148
+ const inter = Inter({ subsets: ["latin"], display: "swap" });
149
+
125
150
  export const metadata: Metadata = site.meta({ title: ${JSON.stringify(ctx.template.siteName)} });
126
151
 
127
152
  export default function RootLayout({ children }: { children: React.ReactNode }) {
128
153
  return (
129
- <html lang="en">
130
- <body>
154
+ <html lang="en" className={inter.className}>
155
+ <body className="antialiased">
131
156
  {children}
132
157
  <script
133
158
  type="application/ld+json"
@@ -138,6 +163,113 @@ export default function RootLayout({ children }: { children: React.ReactNode })
138
163
  );
139
164
  }
140
165
  `;
166
+ var ogRoute = (ctx) => `import { ImageResponse } from "next/og";
167
+ import { site } from "@/lib/site";
168
+
169
+ // \u2728 Dynamic Open Graph images \u2014 every page gets a gorgeous social card,
170
+ // generated on the fly at /og?title=Your+Page+Title. No design tool needed.
171
+ export const runtime = "edge";
172
+
173
+ export function GET(req: Request) {
174
+ const title = new URL(req.url).searchParams.get("title") ?? site.config.name;
175
+ return new ImageResponse(
176
+ (
177
+ <div
178
+ style={{
179
+ width: "100%", height: "100%", display: "flex", flexDirection: "column",
180
+ justifyContent: "center", padding: "90px",
181
+ background: "linear-gradient(135deg, ${ctx.template.accent[0]}, ${ctx.template.accent[1]})",
182
+ color: "white", fontFamily: "sans-serif",
183
+ }}
184
+ >
185
+ <div style={{ fontSize: 72, fontWeight: 800, lineHeight: 1.05, letterSpacing: "-0.02em" }}>{title}</div>
186
+ <div style={{ marginTop: 28, fontSize: 34, opacity: 0.85 }}>{site.config.name}</div>
187
+ </div>
188
+ ),
189
+ { width: 1200, height: 630 },
190
+ );
191
+ }
192
+ `;
193
+ var notFound = () => `import Link from "next/link";
194
+
195
+ export default function NotFound() {
196
+ return (
197
+ <main className="flex min-h-screen flex-col items-center justify-center gap-6 px-6 text-center">
198
+ <div className="text-8xl font-black gradient-text">404</div>
199
+ <p className="text-lg text-white/60">This page wandered off.</p>
200
+ <Link href="/" className="gradient-bg rounded-full px-6 py-3 font-semibold text-black">Back home</Link>
201
+ </main>
202
+ );
203
+ }
204
+ `;
205
+ var manifestTs = (ctx) => `import type { MetadataRoute } from "next";
206
+ import { site } from "@/lib/site";
207
+
208
+ export default function manifest(): MetadataRoute.Manifest {
209
+ return {
210
+ name: site.config.name,
211
+ short_name: site.config.name,
212
+ description: site.config.description,
213
+ start_url: "/",
214
+ display: "standalone",
215
+ background_color: "#0a0a0f",
216
+ theme_color: "${ctx.template.accent[0]}",
217
+ };
218
+ }
219
+ `;
220
+ var envExample = () => `# Your production URL \u2014 powers canonical URLs, sitemap, robots and OG images.
221
+ NEXT_PUBLIC_SITE_URL=https://example.com
222
+ `;
223
+ var welcomeMd = (ctx) => `# \u{1F381} Welcome to ${ctx.name}
224
+
225
+ You didn't get a blank page \u2014 you got a running, good-looking **${ctx.template.label}** with the
226
+ boring-but-essential stuff already done. Here's what's in the box.
227
+
228
+ ## \u2705 Already set up for you
229
+
230
+ - **Beautiful home page** \u2014 styled with Tailwind v4, Inter font, dark theme + gradient accent.
231
+ - **SEO** \u2014 metadata, Open Graph, Twitter cards & JSON-LD, all from one file (\`lib/site.ts\`).
232
+ - **\u2728 Dynamic OG images** \u2014 every page auto-generates a social-share card at \`/og\`. Share a link and see.
233
+ - **Security headers** \u2014 HSTS, CSP, X-Frame-Options and more, via \`next.config.mjs\`.
234
+ - **robots.txt + sitemap.xml** \u2014 generated from your site config. No hand-editing.
235
+ - **A styled 404** and a **PWA manifest** \u2014 the finishing touches most starters skip.
236
+
237
+ ## \u{1F680} Run it
238
+
239
+ \`\`\`bash
240
+ npm run dev # http://localhost:3000
241
+ \`\`\`
242
+
243
+ ## \u{1F3A8} Make it yours (start here)
244
+
245
+ 1. Edit **\`lib/site.ts\`** \u2014 your name, URL and description flow into SEO, sitemap, robots and OG.
246
+ 2. Edit **\`app/page.tsx\`** \u2014 your home page.
247
+ 3. Set **\`NEXT_PUBLIC_SITE_URL\`** in \`.env\` before deploying (copy \`.env.example\`).
248
+
249
+ ## \u{1F389} Surprise: 49 more Lacspace packages, one install away
250
+
251
+ Your app is wired for the whole ecosystem. Drop any of these in \u2014 all zero-dependency:
252
+
253
+ \`\`\`bash
254
+ npm i @lacspace/id # uuidv7, nanoid, short ids
255
+ npm i @lacspace/pdf # invoices & receipts, no headless browser
256
+ npm i @lacspace/signed-url # magic-login & expiring download links
257
+ npm i @lacspace/webhooks # sign / verify / deliver webhooks
258
+ npm i @lacspace/flags # feature flags & A/B, no SaaS
259
+ npm i @lacspace/humanize # "1.5 KB", "3 hours ago", "1.2M"
260
+ \`\`\`
261
+
262
+ Browse them all \u2192 **https://lacspace.com/packages**
263
+
264
+ ## \u2601\uFE0F Deploy
265
+
266
+ Push to GitHub and import on **[Vercel](https://vercel.com/new)** \u2014 it just works. Remember to set
267
+ \`NEXT_PUBLIC_SITE_URL\` to your real domain.
268
+
269
+ ---
270
+
271
+ Built with \u2764\uFE0F using [Lacspace](https://lacspace.com/packages). This app is yours under the Lacspace Free Licence.
272
+ `;
141
273
  var robotsTs = () => `import { robotsForSite } from "@lacspace/robots";
142
274
  import { site } from "@/lib/site";
143
275
 
@@ -276,6 +408,131 @@ function homePage(ctx) {
276
408
  </section>
277
409
  ${FOOTER(n)}`);
278
410
  }
411
+ if (ctx.template.key === "blog") {
412
+ return shell(`${NAV(n, ["Latest", "Topics", "About"])}
413
+ <section className="mx-auto max-w-3xl px-6 py-24">
414
+ <p className="mb-3 text-sm font-semibold uppercase tracking-widest text-white/40">The Journal</p>
415
+ <h1 className="text-5xl font-black leading-tight sm:text-6xl gradient-text">${n}</h1>
416
+ <p className="mt-6 text-lg text-white/60">${ctx.template.siteDescription}</p>
417
+ </section>
418
+ <section id="latest" className="mx-auto max-w-5xl px-6 pb-8">
419
+ <a href="#" className="group block rounded-3xl border border-white/10 bg-white/[0.02] p-8 transition hover:border-white/20">
420
+ <div className="mb-6 h-56 rounded-2xl gradient-bg opacity-80" />
421
+ <span className="text-xs font-semibold uppercase tracking-wider text-white/40">Featured</span>
422
+ <h2 className="mt-2 text-3xl font-bold group-hover:opacity-90">The one thing every product needs before launch</h2>
423
+ <p className="mt-2 text-white/60">A short, punchy dek that pulls the reader into the piece and makes them want more.</p>
424
+ </a>
425
+ </section>
426
+ <section className="mx-auto max-w-5xl px-6 py-12">
427
+ <div className="grid gap-8 sm:grid-cols-2">
428
+ {[1, 2, 3, 4].map((i) => (
429
+ <a key={i} href="#" className="group">
430
+ <div className="mb-4 h-40 rounded-xl gradient-bg opacity-70" />
431
+ <span className="text-xs uppercase tracking-wider text-white/40">Essay</span>
432
+ <h3 className="mt-1 text-xl font-semibold group-hover:opacity-90">A thoughtful headline for post {i}</h3>
433
+ <p className="mt-1 text-sm text-white/50">Two lines of supporting copy to set the scene for the reader.</p>
434
+ </a>
435
+ ))}
436
+ </div>
437
+ </section>
438
+ ${FOOTER(n)}`);
439
+ }
440
+ if (ctx.template.key === "docs") {
441
+ return shell(`${NAV(n, ["Guides", "API", "Examples"])}
442
+ <section className="mx-auto max-w-4xl px-6 py-28 text-center">
443
+ <h1 className="text-5xl font-black leading-tight sm:text-6xl"><span className="gradient-text">${n}</span></h1>
444
+ <p className="mx-auto mt-6 max-w-2xl text-lg text-white/60">${ctx.template.siteDescription}</p>
445
+ <div className="mt-8 inline-flex items-center gap-3 rounded-lg border border-white/10 bg-black/40 px-4 py-3 font-mono text-sm text-white/80">
446
+ <span className="text-white/40">$</span> npm install @acme/sdk
447
+ </div>
448
+ </section>
449
+ <section id="guides" className="mx-auto max-w-6xl px-6 py-12">
450
+ <div className="grid gap-6 md:grid-cols-3">
451
+ {[
452
+ { t: "Quick start", d: "Go from zero to your first request in five minutes." },
453
+ { t: "Guides", d: "Task-focused walkthroughs for the common paths." },
454
+ { t: "API reference", d: "Every endpoint, typed, with copy-paste examples." },
455
+ ].map((c) => (
456
+ <a key={c.t} href="#" className="rounded-2xl border border-white/10 bg-white/[0.02] p-8 transition hover:border-white/20">
457
+ <h3 className="text-xl font-bold gradient-text">{c.t}</h3>
458
+ <p className="mt-2 text-white/60">{c.d}</p>
459
+ </a>
460
+ ))}
461
+ </div>
462
+ </section>
463
+ ${FOOTER(n)}`);
464
+ }
465
+ if (ctx.template.key === "dashboard") {
466
+ return shell(`<div className="flex min-h-screen">
467
+ <aside className="hidden w-56 shrink-0 border-r border-white/10 p-6 md:block">
468
+ <div className="mb-8 text-lg font-black gradient-text">${n}</div>
469
+ <nav className="space-y-1 text-sm text-white/60">
470
+ {["Overview", "Analytics", "Customers", "Settings"].map((l) => (
471
+ <a key={l} href="#" className="block rounded-lg px-3 py-2 hover:bg-white/5 hover:text-white">{l}</a>
472
+ ))}
473
+ </nav>
474
+ </aside>
475
+ <main className="flex-1 p-6 md:p-10">
476
+ <h1 className="text-2xl font-bold">Overview</h1>
477
+ <p className="mt-1 text-white/50">${ctx.template.siteDescription}</p>
478
+ <div className="mt-8 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
479
+ {[
480
+ { l: "Revenue", v: "$48.2k", c: "+12%" }, { l: "Users", v: "12,480", c: "+3.4%" },
481
+ { l: "Orders", v: "1,204", c: "+8%" }, { l: "Churn", v: "1.2%", c: "-0.3%" },
482
+ ].map((s) => (
483
+ <div key={s.l} className="rounded-2xl border border-white/10 bg-white/[0.02] p-5">
484
+ <div className="text-sm text-white/50">{s.l}</div>
485
+ <div className="mt-1 text-2xl font-bold">{s.v}</div>
486
+ <div className="mt-1 text-xs text-emerald-400">{s.c}</div>
487
+ </div>
488
+ ))}
489
+ </div>
490
+ <div className="mt-6 rounded-2xl border border-white/10 bg-white/[0.02] p-6">
491
+ <div className="mb-4 font-semibold">Recent activity</div>
492
+ <div className="space-y-3">
493
+ {[1, 2, 3, 4].map((i) => (
494
+ <div key={i} className="flex items-center justify-between border-b border-white/5 pb-3 text-sm">
495
+ <span className="text-white/70">Event #{i}</span>
496
+ <span className="text-white/40">just now</span>
497
+ </div>
498
+ ))}
499
+ </div>
500
+ </div>
501
+ </main>
502
+ </div>`);
503
+ }
504
+ if (ctx.template.key === "restaurant") {
505
+ return shell(`${NAV(n, ["Menu", "Story", "Reserve"])}
506
+ <section className="mx-auto max-w-4xl px-6 py-28 text-center">
507
+ <p className="mb-4 text-sm font-semibold uppercase tracking-widest text-white/40">Est. 2026</p>
508
+ <h1 className="text-5xl font-black leading-tight sm:text-7xl gradient-text">${n}</h1>
509
+ <p className="mx-auto mt-6 max-w-xl text-lg text-white/60">${ctx.template.siteDescription}</p>
510
+ <a href="#reserve" className="mt-10 inline-block gradient-bg rounded-full px-8 py-3 font-semibold text-black">Reserve a table</a>
511
+ </section>
512
+ <section id="menu" className="mx-auto max-w-4xl px-6 py-16">
513
+ <h2 className="mb-10 text-center text-3xl font-bold">Tonight's plates</h2>
514
+ <div className="grid gap-6 sm:grid-cols-2">
515
+ {[
516
+ { n: "Charred leeks", p: "$14" }, { n: "Handmade tagliatelle", p: "$22" },
517
+ { n: "Wood-fired trout", p: "$28" }, { n: "Olive oil cake", p: "$11" },
518
+ ].map((d) => (
519
+ <div key={d.n} className="flex items-baseline justify-between gap-4 border-b border-white/10 pb-4">
520
+ <div>
521
+ <h3 className="text-lg font-semibold">{d.n}</h3>
522
+ <p className="text-sm text-white/50">A short, mouth-watering description of the dish.</p>
523
+ </div>
524
+ <span className="shrink-0 gradient-text font-bold">{d.p}</span>
525
+ </div>
526
+ ))}
527
+ </div>
528
+ </section>
529
+ <section id="reserve" className="mx-auto max-w-2xl px-6 py-24 text-center">
530
+ <h2 className="text-3xl font-bold">Join us</h2>
531
+ <p className="mt-3 text-white/60">Open Wed\u2013Sun, 5pm till late. Walk-ins welcome; bookings recommended.</p>
532
+ <a href="tel:+10000000000" className="mt-8 inline-block rounded-full border border-white/20 px-8 py-3 font-semibold hover:bg-white/5">Call to book</a>
533
+ </section>
534
+ ${FOOTER(n)}`);
535
+ }
279
536
  return shell(`${NAV(n, ["Features", "Pricing", "Sign in"])}
280
537
  <section className="mx-auto max-w-4xl px-6 py-28 text-center">
281
538
  <p className="mb-4 inline-block rounded-full border border-white/15 px-4 py-1 text-xs font-semibold text-white/60">New \xB7 v1.0</p>
@@ -321,8 +578,13 @@ function buildFiles(ctx) {
321
578
  "app/layout.tsx": layout(ctx),
322
579
  "app/globals.css": globalsCss(ctx),
323
580
  "app/page.tsx": homePage(ctx),
581
+ "app/not-found.tsx": notFound(),
582
+ "app/og/route.tsx": ogRoute(ctx),
583
+ "app/manifest.ts": manifestTs(ctx),
324
584
  "app/robots.txt/route.ts": robotsTs(),
325
- "app/sitemap.xml/route.ts": sitemapTs()
585
+ "app/sitemap.xml/route.ts": sitemapTs(),
586
+ ".env.example": envExample(),
587
+ "WELCOME.md": welcomeMd(ctx)
326
588
  };
327
589
  }
328
590
  function parseArgs(list) {
package/package.json CHANGED
@@ -1,17 +1,51 @@
1
1
  {
2
2
  "name": "create-lacspace-app",
3
- "version": "1.0.0",
4
- "description": "Scaffold a beautiful, production-ready Next.js app from a Lacspace template — personal portfolio, business site, e-commerce or SaaS landing — pre-wired with SEO metadata + JSON-LD, security headers, sitemap and robots. Like create-next-app, but you start gorgeous.",
3
+ "version": "1.2.0",
4
+ "description": "Scaffold a beautiful, production-ready Next.js app from a Lacspace template — portfolio, business, e-commerce, SaaS, blog, docs, dashboard or restaurant — pre-wired with SEO, security headers, sitemap and robots. Like create-next-app, but you start gorgeous.",
5
5
  "type": "module",
6
- "bin": { "create-lacspace-app": "./dist/index.js" },
7
- "files": ["dist"],
8
- "scripts": { "build": "tsup", "prepublishOnly": "npm run build" },
9
- "keywords": ["create-lacspace-app", "nextjs", "next-app", "starter", "template", "scaffold", "boilerplate", "portfolio-template", "ecommerce-template", "saas-template", "cli", "create-next-app-alternative", "typescript"],
6
+ "bin": {
7
+ "create-lacspace-app": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsup",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "keywords": [
17
+ "create-lacspace-app",
18
+ "nextjs",
19
+ "next-app",
20
+ "starter",
21
+ "template",
22
+ "scaffold",
23
+ "boilerplate",
24
+ "portfolio-template",
25
+ "ecommerce-template",
26
+ "saas-template",
27
+ "blog-template",
28
+ "dashboard-template",
29
+ "docs-template",
30
+ "cli",
31
+ "create-next-app-alternative",
32
+ "typescript"
33
+ ],
10
34
  "author": "Lacspace <contact@lacspace.com>",
11
35
  "license": "SEE LICENSE IN LICENSE",
12
36
  "homepage": "https://lacspace.com/packages",
13
- "repository": { "type": "git", "url": "git+https://github.com/lacspace/npm-packages.git", "directory": "create-lacspace-app" },
14
- "bugs": { "url": "https://github.com/lacspace/npm-packages/issues" },
15
- "engines": { "node": ">=18" },
16
- "publishConfig": { "access": "public" }
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/lacspace/npm-packages.git",
40
+ "directory": "create-lacspace-app"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/lacspace/npm-packages/issues"
44
+ },
45
+ "engines": {
46
+ "node": ">=18"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ }
17
51
  }