create-githat-app 1.2.3 → 1.4.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 (157) hide show
  1. package/README.md +48 -18
  2. package/dist/cli.js +1161 -114
  3. package/package.json +34 -9
  4. package/templates/agent/app/(auth)/sign-in/page.tsx.hbs +9 -0
  5. package/templates/agent/app/(auth)/sign-up/page.tsx.hbs +9 -0
  6. package/templates/agent/app/admin/agent/page.tsx.hbs +127 -0
  7. package/templates/agent/app/globals.css.hbs +87 -0
  8. package/templates/agent/app/layout.tsx.hbs +41 -0
  9. package/templates/agent/app/page.tsx.hbs +100 -0
  10. package/templates/agent/next.config.ts.hbs +8 -0
  11. package/templates/agent/postcss.config.mjs.hbs +14 -0
  12. package/templates/agent/proxy.ts.hbs +10 -0
  13. package/templates/agent/tsconfig.json.hbs +21 -0
  14. package/templates/base/.env.example.hbs +2 -2
  15. package/templates/base/.env.local.example.hbs +20 -0
  16. package/templates/base/.env.local.hbs +13 -2
  17. package/templates/base/.github/CODEOWNERS.hbs +1 -0
  18. package/templates/base/.github/SECURITY.md +10 -0
  19. package/templates/base/.github/dependabot.yml +19 -0
  20. package/templates/base/.github/workflows/ci.yml.hbs +77 -0
  21. package/templates/base/.github/workflows/githat-policy.yml +51 -0
  22. package/templates/base/.gitignore.hbs +17 -2
  23. package/templates/base/README.md.hbs +31 -52
  24. package/templates/classroom/app/(auth)/sign-in/page.tsx.hbs +9 -0
  25. package/templates/classroom/app/(auth)/sign-up/page.tsx.hbs +9 -0
  26. package/templates/classroom/app/globals.css.hbs +87 -0
  27. package/templates/classroom/app/layout.tsx.hbs +41 -0
  28. package/templates/classroom/app/page.tsx.hbs +103 -0
  29. package/templates/classroom/app/projects/[id]/feedback/page.tsx.hbs +159 -0
  30. package/templates/classroom/app/projects/[id]/present/page.tsx.hbs +113 -0
  31. package/templates/classroom/next.config.ts.hbs +8 -0
  32. package/templates/classroom/postcss.config.mjs.hbs +14 -0
  33. package/templates/classroom/proxy.ts.hbs +10 -0
  34. package/templates/classroom/tsconfig.json.hbs +21 -0
  35. package/templates/content/app/(auth)/sign-in/page.tsx.hbs +9 -0
  36. package/templates/content/app/(auth)/sign-up/page.tsx.hbs +9 -0
  37. package/templates/content/app/globals.css.hbs +87 -0
  38. package/templates/content/app/layout.tsx.hbs +41 -0
  39. package/templates/content/app/newsletter/page.tsx.hbs +90 -0
  40. package/templates/content/app/page.tsx.hbs +105 -0
  41. package/templates/content/app/posts/[slug]/page.tsx.hbs +119 -0
  42. package/templates/content/next.config.ts.hbs +8 -0
  43. package/templates/content/postcss.config.mjs.hbs +14 -0
  44. package/templates/content/proxy.ts.hbs +10 -0
  45. package/templates/content/tsconfig.json.hbs +21 -0
  46. package/templates/dashboard/app/(auth)/sign-in/page.tsx.hbs +9 -0
  47. package/templates/dashboard/app/(auth)/sign-up/page.tsx.hbs +9 -0
  48. package/templates/dashboard/app/admin/data/[entity]/page.tsx.hbs +68 -0
  49. package/templates/dashboard/app/admin/page.tsx.hbs +59 -0
  50. package/templates/dashboard/app/globals.css.hbs +87 -0
  51. package/templates/dashboard/app/layout.tsx.hbs +41 -0
  52. package/templates/dashboard/app/page.tsx.hbs +57 -0
  53. package/templates/dashboard/next.config.ts.hbs +8 -0
  54. package/templates/dashboard/postcss.config.mjs.hbs +14 -0
  55. package/templates/dashboard/proxy.ts.hbs +10 -0
  56. package/templates/dashboard/src/lib/db.ts.hbs +39 -0
  57. package/templates/dashboard/tsconfig.json.hbs +21 -0
  58. package/templates/fullstack/apps-api-express/.env.example.hbs +6 -0
  59. package/templates/fullstack/apps-api-express/.env.local.hbs +6 -0
  60. package/templates/fullstack/apps-api-express/package.json.hbs +24 -0
  61. package/templates/fullstack/apps-api-express/src/index.ts.hbs +41 -0
  62. package/templates/fullstack/apps-api-express/src/routes/health.ts.hbs +11 -0
  63. package/templates/fullstack/apps-api-express/src/routes/users.ts.hbs +43 -0
  64. package/templates/fullstack/apps-api-express/tsconfig.json.hbs +16 -0
  65. package/templates/fullstack/apps-api-fastify/.env.example.hbs +6 -0
  66. package/templates/fullstack/apps-api-fastify/.env.local.hbs +6 -0
  67. package/templates/fullstack/apps-api-fastify/package.json.hbs +22 -0
  68. package/templates/fullstack/apps-api-fastify/src/index.ts.hbs +28 -0
  69. package/templates/fullstack/apps-api-fastify/src/routes/health.ts.hbs +11 -0
  70. package/templates/fullstack/apps-api-fastify/src/routes/users.ts.hbs +43 -0
  71. package/templates/fullstack/apps-api-fastify/tsconfig.json.hbs +16 -0
  72. package/templates/fullstack/apps-api-hono/.env.example.hbs +6 -0
  73. package/templates/fullstack/apps-api-hono/.env.local.hbs +6 -0
  74. package/templates/fullstack/apps-api-hono/package.json.hbs +22 -0
  75. package/templates/fullstack/apps-api-hono/src/index.ts.hbs +35 -0
  76. package/templates/fullstack/apps-api-hono/src/routes/health.ts.hbs +11 -0
  77. package/templates/fullstack/apps-api-hono/src/routes/users.ts.hbs +43 -0
  78. package/templates/fullstack/apps-api-hono/tsconfig.json.hbs +16 -0
  79. package/templates/fullstack/apps-web-nextjs/.env.example.hbs +5 -0
  80. package/templates/fullstack/apps-web-nextjs/.env.local.hbs +5 -0
  81. package/templates/fullstack/apps-web-nextjs/app/(auth)/forgot-password/page.tsx.hbs +11 -0
  82. package/templates/fullstack/apps-web-nextjs/app/(auth)/reset-password/page.tsx.hbs +39 -0
  83. package/templates/fullstack/apps-web-nextjs/app/(auth)/sign-in/page.tsx.hbs +9 -0
  84. package/templates/fullstack/apps-web-nextjs/app/(auth)/sign-up/page.tsx.hbs +9 -0
  85. package/templates/fullstack/apps-web-nextjs/app/(auth)/verify-email/page.tsx.hbs +11 -0
  86. package/templates/fullstack/apps-web-nextjs/app/dashboard/layout.tsx.hbs +15 -0
  87. package/templates/fullstack/apps-web-nextjs/app/dashboard/page.tsx.hbs +27 -0
  88. package/templates/fullstack/apps-web-nextjs/app/globals.css.hbs +21 -0
  89. package/templates/fullstack/apps-web-nextjs/app/layout.tsx.hbs +30 -0
  90. package/templates/fullstack/apps-web-nextjs/app/page.tsx.hbs +17 -0
  91. package/templates/fullstack/apps-web-nextjs/next.config.ts.hbs +16 -0
  92. package/templates/fullstack/apps-web-nextjs/package.json.hbs +34 -0
  93. package/templates/fullstack/apps-web-nextjs/postcss.config.mjs.hbs +9 -0
  94. package/templates/fullstack/apps-web-nextjs/tsconfig.json.hbs +21 -0
  95. package/templates/fullstack/root/.gitignore.hbs +42 -0
  96. package/templates/fullstack/root/githat.yaml.hbs +17 -0
  97. package/templates/fullstack/root/package.json.hbs +15 -0
  98. package/templates/fullstack/root/turbo.json.hbs +20 -0
  99. package/templates/marketplace/CULTURE.md +74 -0
  100. package/templates/marketplace/app/(auth)/sign-in/page.tsx.hbs +9 -0
  101. package/templates/marketplace/app/(auth)/sign-up/page.tsx.hbs +9 -0
  102. package/templates/marketplace/app/(shop)/[slug]/p/[productId]/page.tsx.hbs +99 -0
  103. package/templates/marketplace/app/(shop)/[slug]/page.tsx.hbs +90 -0
  104. package/templates/marketplace/app/admin/page.tsx.hbs +95 -0
  105. package/templates/marketplace/app/cart/page.tsx.hbs +157 -0
  106. package/templates/marketplace/app/globals.css.hbs +87 -0
  107. package/templates/marketplace/app/layout.tsx.hbs +77 -0
  108. package/templates/marketplace/app/page.tsx.hbs +178 -0
  109. package/templates/marketplace/app/sell/page.tsx.hbs +78 -0
  110. package/templates/marketplace/next.config.ts.hbs +8 -0
  111. package/templates/marketplace/postcss.config.mjs.hbs +14 -0
  112. package/templates/marketplace/proxy.ts.hbs +10 -0
  113. package/templates/marketplace/src/lib/anon-session.ts.hbs +117 -0
  114. package/templates/marketplace/src/lib/categories.ts.hbs +35 -0
  115. package/templates/marketplace/tsconfig.json.hbs +21 -0
  116. package/templates/nextjs/.github/workflows/deploy.yml.hbs +107 -0
  117. package/templates/nextjs/app/(auth)/reset-password/page.tsx.hbs +106 -0
  118. package/templates/nextjs/app/globals.css.hbs +4 -3
  119. package/templates/nextjs/app/layout.tsx.hbs +5 -1
  120. package/templates/nextjs/app/page.tsx.hbs +3 -6
  121. package/templates/nextjs/next.config.ts.hbs +5 -2
  122. package/templates/nextjs/proxy.ts.hbs +10 -0
  123. package/templates/plain/app/(auth)/sign-in/page.tsx.hbs +9 -0
  124. package/templates/plain/app/(auth)/sign-up/page.tsx.hbs +9 -0
  125. package/templates/plain/app/globals.css.hbs +87 -0
  126. package/templates/plain/app/layout.tsx.hbs +41 -0
  127. package/templates/plain/app/page.tsx.hbs +123 -0
  128. package/templates/plain/next.config.ts.hbs +8 -0
  129. package/templates/plain/postcss.config.mjs.hbs +14 -0
  130. package/templates/plain/proxy.ts.hbs +10 -0
  131. package/templates/plain/tsconfig.json.hbs +21 -0
  132. package/templates/portfolio/app/(auth)/sign-in/page.tsx.hbs +9 -0
  133. package/templates/portfolio/app/(auth)/sign-up/page.tsx.hbs +9 -0
  134. package/templates/portfolio/app/globals.css.hbs +87 -0
  135. package/templates/portfolio/app/layout.tsx.hbs +41 -0
  136. package/templates/portfolio/app/page.tsx.hbs +86 -0
  137. package/templates/portfolio/next.config.ts.hbs +8 -0
  138. package/templates/portfolio/postcss.config.mjs.hbs +14 -0
  139. package/templates/portfolio/proxy.ts.hbs +10 -0
  140. package/templates/portfolio/tsconfig.json.hbs +21 -0
  141. package/templates/react-vite/src/App.tsx.hbs +11 -9
  142. package/templates/react-vite/src/index.css.hbs +4 -3
  143. package/templates/react-vite/src/pages/Home.tsx.hbs +3 -6
  144. package/templates/saas/app/(auth)/sign-in/page.tsx.hbs +9 -0
  145. package/templates/saas/app/(auth)/sign-up/page.tsx.hbs +9 -0
  146. package/templates/saas/app/admin/billing/page.tsx.hbs +145 -0
  147. package/templates/saas/app/admin/page.tsx.hbs +106 -0
  148. package/templates/saas/app/admin/team/page.tsx.hbs +134 -0
  149. package/templates/saas/app/globals.css.hbs +87 -0
  150. package/templates/saas/app/layout.tsx.hbs +41 -0
  151. package/templates/saas/app/page.tsx.hbs +108 -0
  152. package/templates/saas/app/pricing/page.tsx.hbs +131 -0
  153. package/templates/saas/next.config.ts.hbs +8 -0
  154. package/templates/saas/postcss.config.mjs.hbs +14 -0
  155. package/templates/saas/proxy.ts.hbs +10 -0
  156. package/templates/saas/tsconfig.json.hbs +21 -0
  157. package/templates/nextjs/middleware.ts.hbs +0 -10
@@ -0,0 +1,123 @@
1
+ 'use client';
2
+
3
+ import { SignInButton, SignUpButton, UserButton, useAuth } from '@githat/nextjs';
4
+
5
+ /**
6
+ * Plain GitHat homepage.
7
+ *
8
+ * No dashboard, no orgs, no agents — just one page that flips between
9
+ * "signed out" and "signed in." The smallest possible example of "I
10
+ * have GitHat wired up." Replace this file with whatever your app
11
+ * actually does — auth keeps working.
12
+ */
13
+ export default function Home() {
14
+ const { isSignedIn, isLoading, user } = useAuth();
15
+
16
+ if (isLoading) {
17
+ return (
18
+ <div
19
+ style=\{{
20
+ display: 'flex',
21
+ minHeight: 'calc(100vh - 64px)',
22
+ alignItems: 'center',
23
+ justifyContent: 'center',
24
+ color: 'var(--fg-muted)',
25
+ }}
26
+ >
27
+ Loading…
28
+ </div>
29
+ );
30
+ }
31
+
32
+ return (
33
+ <div
34
+ style=\{{
35
+ display: 'flex',
36
+ minHeight: 'calc(100vh - 64px)',
37
+ alignItems: 'center',
38
+ justifyContent: 'center',
39
+ padding: 'var(--space-8) var(--space-4)',
40
+ background: 'var(--bg)',
41
+ }}
42
+ >
43
+ <main
44
+ style=\{{
45
+ width: '100%',
46
+ maxWidth: '32rem',
47
+ textAlign: 'center',
48
+ color: 'var(--fg)',
49
+ }}
50
+ >
51
+ {!isSignedIn ? (
52
+ <>
53
+ <h1
54
+ style=\{{
55
+ fontFamily: 'var(--font-wordmark)',
56
+ fontSize: '2.5rem',
57
+ lineHeight: 1.1,
58
+ marginBottom: 'var(--space-3)',
59
+ }}
60
+ >
61
+ Welcome to {{businessName}}
62
+ </h1>
63
+ <p
64
+ style=\{{
65
+ color: 'var(--fg-muted)',
66
+ marginBottom: 'var(--space-6)',
67
+ lineHeight: 1.6,
68
+ }}
69
+ >
70
+ Sign in to continue, or create an account in 30 seconds.
71
+ We use GitHat for identity — your password never touches
72
+ this app.
73
+ </p>
74
+ <div
75
+ style=\{{
76
+ display: 'flex',
77
+ gap: 'var(--space-3)',
78
+ justifyContent: 'center',
79
+ flexWrap: 'wrap',
80
+ }}
81
+ >
82
+ <SignInButton />
83
+ <SignUpButton />
84
+ </div>
85
+ </>
86
+ ) : (
87
+ <>
88
+ <div
89
+ style=\{{
90
+ display: 'flex',
91
+ alignItems: 'center',
92
+ justifyContent: 'center',
93
+ gap: 'var(--space-4)',
94
+ marginBottom: 'var(--space-6)',
95
+ }}
96
+ >
97
+ <UserButton />
98
+ <h1
99
+ style=\{{
100
+ fontFamily: 'var(--font-wordmark)',
101
+ fontSize: '2rem',
102
+ margin: 0,
103
+ }}
104
+ >
105
+ Hello{user?.name ? `, ${user.name}` : ''}.
106
+ </h1>
107
+ </div>
108
+ <p
109
+ style=\{{
110
+ color: 'var(--fg-muted)',
111
+ lineHeight: 1.6,
112
+ }}
113
+ >
114
+ That's it. The plain template doesn't ship a dashboard or
115
+ any other route — replace this page with whatever your
116
+ app actually does. Authentication will keep working.
117
+ </p>
118
+ </>
119
+ )}
120
+ </main>
121
+ </div>
122
+ );
123
+ }
@@ -0,0 +1,8 @@
1
+ import type { NextConfig } from 'next';
2
+ import { withGitHat } from '@githat/nextjs/server';
3
+
4
+ const nextConfig: NextConfig = {
5
+ output: 'standalone',
6
+ };
7
+
8
+ export default withGitHat(nextConfig);
@@ -0,0 +1,14 @@
1
+ /*
2
+ * Plain template — Tailwind v4 PostCSS plugin is required even though
3
+ * the plain scaffold doesn't use Tailwind utility classes. The auth
4
+ * page CSS shipped by `@githat/nextjs/styles` is processed through
5
+ * @tailwindcss/postcss at build time. Drop this config and the
6
+ * auth pages render unstyled.
7
+ */
8
+ const config = {
9
+ plugins: {
10
+ '@tailwindcss/postcss': {},
11
+ },
12
+ };
13
+
14
+ export default config;
@@ -0,0 +1,10 @@
1
+ import { authProxy } from '@githat/nextjs/proxy';
2
+
3
+ export const proxy = authProxy({
4
+ publicRoutes: ['/', '/sign-in', '/sign-up'{{#if includeForgotPassword}}, '/forgot-password', '/reset-password'{{/if}}{{#if includeEmailVerification}}, '/verify-email'{{/if}}],
5
+ signInUrl: '/sign-in',
6
+ });
7
+
8
+ export const config = {
9
+ matcher: ['/((?!_next|api|.*\\..*).*)'],
10
+ };
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [{ "name": "next" }],
17
+ "paths": { "@/*": ["./*"] }
18
+ },
19
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
20
+ "exclude": ["node_modules"]
21
+ }
@@ -0,0 +1,9 @@
1
+ import { SignInForm } from '@githat/nextjs';
2
+
3
+ export default function SignInPage() {
4
+ return (
5
+ <main {{#if useTailwind}}className="flex items-center justify-center min-h-screen bg-[#09090b]"{{else}}style=\{{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#09090b' }}{{/if}}>
6
+ <SignInForm signUpUrl="/sign-up" {{#if includeForgotPassword}}forgotPasswordUrl="/forgot-password"{{/if}} />
7
+ </main>
8
+ );
9
+ }
@@ -0,0 +1,9 @@
1
+ import { SignUpForm } from '@githat/nextjs';
2
+
3
+ export default function SignUpPage() {
4
+ return (
5
+ <main {{#if useTailwind}}className="flex items-center justify-center min-h-screen bg-[#09090b]"{{else}}style=\{{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#09090b' }}{{/if}}>
6
+ <SignUpForm signInUrl="/sign-in" />
7
+ </main>
8
+ );
9
+ }
@@ -0,0 +1,87 @@
1
+ /*
2
+ * Tailwind v4 — required because @githat/nextjs/styles is processed
3
+ * through @tailwindcss/postcss. Plain doesn't ship utility classes,
4
+ * but the import is needed for the auth pages to render styled.
5
+ */
6
+ @import "tailwindcss";
7
+
8
+ /*
9
+ * Plain template — self-contained globals.
10
+ *
11
+ * Defines the minimum CSS variables a GitHat app uses for layout and
12
+ * the auth-page styling that ships with @githat/nextjs/styles.
13
+ * Override these in your own files when you want a real theme.
14
+ *
15
+ * Light theme by default; flip --bg/--fg for dark.
16
+ */
17
+
18
+ :root {
19
+ /* Surface */
20
+ --bg: #ffffff;
21
+ --surface: #fafafa;
22
+ --surface-sub: #f4f4f5;
23
+
24
+ /* Borders */
25
+ --border: #e5e7eb;
26
+
27
+ /* Foreground */
28
+ --fg: #0a0a0a;
29
+ --fg-muted: #525252;
30
+ --fg-subtle: #737373;
31
+
32
+ /* Brand — change these two to re-skin the whole auth flow */
33
+ --primary: #6366f1;
34
+ --accent: #f59e0b;
35
+
36
+ /* Semantic */
37
+ --success: #16a34a;
38
+ --warn: #d97706;
39
+ --danger: #dc2626;
40
+
41
+ /* Spacing — used by @githat/nextjs/styles */
42
+ --space-1: 0.25rem;
43
+ --space-2: 0.5rem;
44
+ --space-3: 0.75rem;
45
+ --space-4: 1rem;
46
+ --space-6: 1.5rem;
47
+ --space-8: 2rem;
48
+
49
+ /* Radius */
50
+ --radius: 0.5rem;
51
+ --radius-md: 0.5rem;
52
+ --radius-lg: 0.75rem;
53
+
54
+ /* Fonts */
55
+ --font-sans: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
56
+ --font-wordmark: 'Instrument Serif', Georgia, serif;
57
+ }
58
+
59
+ @media (prefers-color-scheme: dark) {
60
+ :root {
61
+ --bg: #0a0a0a;
62
+ --surface: #18181b;
63
+ --surface-sub: #27272a;
64
+ --border: #3f3f46;
65
+ --fg: #fafafa;
66
+ --fg-muted: #a1a1aa;
67
+ --fg-subtle: #71717a;
68
+ }
69
+ }
70
+
71
+ * {
72
+ box-sizing: border-box;
73
+ margin: 0;
74
+ padding: 0;
75
+ }
76
+
77
+ body {
78
+ font-family: var(--font-sans);
79
+ background: var(--bg);
80
+ color: var(--fg);
81
+ line-height: 1.5;
82
+ }
83
+
84
+ a {
85
+ color: inherit;
86
+ text-decoration: none;
87
+ }
@@ -0,0 +1,41 @@
1
+ import { GitHatProvider } from '@githat/nextjs';
2
+ import '@githat/nextjs/styles';
3
+ import './globals.css';
4
+
5
+ export const metadata = {
6
+ title: '{{businessName}}',
7
+ description: '{{description}}',
8
+ };
9
+
10
+ export default function RootLayout({ children }{{#if typescript}}: { children: React.ReactNode }{{/if}}) {
11
+ return (
12
+ <html lang="en">
13
+ <body>
14
+ {/*
15
+ Plain template: no @githat/ui dep, no Wordmark. The
16
+ full-kit (`nextjs`) template uses @githat/ui for the
17
+ shared design system; the plain scaffold is the smallest
18
+ working app, so we avoid extra deps.
19
+ */}
20
+ <GitHatProvider config=\{{
21
+ publishableKey: process.env.NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY || '',
22
+ signInUrl: '/sign-in',
23
+ signUpUrl: '/sign-up',
24
+ afterSignInUrl: '/',
25
+ afterSignOutUrl: '/',
26
+ }}>
27
+ <header style=\{{
28
+ padding: '1rem 1.5rem',
29
+ borderBottom: '1px solid var(--border, #e5e7eb)',
30
+ fontFamily: 'system-ui, -apple-system, sans-serif',
31
+ }}>
32
+ <a href="/" style=\{{ textDecoration: 'none', color: 'inherit', fontWeight: 600 }}>
33
+ {{businessName}}
34
+ </a>
35
+ </header>
36
+ <main>{children}</main>
37
+ </GitHatProvider>
38
+ </body>
39
+ </html>
40
+ );
41
+ }
@@ -0,0 +1,86 @@
1
+ import Link from 'next/link';
2
+
3
+ /**
4
+ * Portfolio homepage.
5
+ *
6
+ * Personal/professional site for showing projects you've shipped.
7
+ * Public reads, auth-gated edits — sign in only when you want to
8
+ * add or edit a project. Replaces Linktree + Cargo + a static
9
+ * site generator + Vercel.
10
+ *
11
+ * Project data is hardcoded for the starter. Real apps store
12
+ * projects in a Postgres / DynamoDB table or in Markdown files,
13
+ * and fetch in this server component.
14
+ */
15
+
16
+ const PROJECTS = [
17
+ {
18
+ slug: 'project-one',
19
+ title: 'A thing I shipped',
20
+ summary: 'Two-line description of the project, what it does, what was hard.',
21
+ year: 2026,
22
+ role: 'Designer + Engineer',
23
+ },
24
+ {
25
+ slug: 'project-two',
26
+ title: 'Another thing',
27
+ summary: 'A research project that turned into a product. Worked for two years.',
28
+ year: 2025,
29
+ role: 'Lead',
30
+ },
31
+ {
32
+ slug: 'project-three',
33
+ title: 'A side project',
34
+ summary: 'Built in a weekend, used by 12 people, learned three things.',
35
+ year: 2025,
36
+ role: 'Solo',
37
+ },
38
+ ];
39
+
40
+ export default function Home() {
41
+ return (
42
+ <div style=\{{ background: 'var(--bg)', color: 'var(--fg)' }}>
43
+ <section style=\{{ padding: 'var(--space-12) var(--space-4)', maxWidth: '40rem', margin: '0 auto' }}>
44
+ <h1 style=\{{
45
+ fontFamily: 'var(--font-wordmark, Georgia, serif)',
46
+ fontSize: 'clamp(2rem, 5vw, 3rem)',
47
+ lineHeight: 1.1,
48
+ marginBottom: 'var(--space-3)',
49
+ }}>
50
+ {{businessName}}
51
+ </h1>
52
+ <p style=\{{ color: 'var(--fg-muted)', fontSize: '1.125rem', lineHeight: 1.7 }}>
53
+ One-paragraph intro. What you do, what you care about, where to find
54
+ the rest of you. Edit this in <code>app/page.tsx</code>.
55
+ <br /><br />
56
+ <Link href="/about" style=\{{ color: 'var(--primary)' }}>More about me →</Link>
57
+ </p>
58
+ </section>
59
+
60
+ <section style=\{{ padding: 'var(--space-8) var(--space-4)', maxWidth: '48rem', margin: '0 auto' }}>
61
+ <h2 style=\{{ fontSize: '1.5rem', marginBottom: 'var(--space-6)' }}>Projects</h2>
62
+ <ul style=\{{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 'var(--space-3)' }}>
63
+ {PROJECTS.map((p) => (
64
+ <li key={p.slug}>
65
+ <Link href={`/${p.slug}`} style=\{{
66
+ display: 'block',
67
+ padding: 'var(--space-5)',
68
+ borderRadius: 'var(--radius-md, 0.5rem)',
69
+ border: '1px solid var(--border)',
70
+ background: 'var(--surface)',
71
+ color: 'var(--fg)',
72
+ textDecoration: 'none',
73
+ }}>
74
+ <div style=\{{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 'var(--space-3)', flexWrap: 'wrap', marginBottom: 'var(--space-2)' }}>
75
+ <h3 style=\{{ fontSize: '1.25rem', fontWeight: 600, margin: 0 }}>{p.title}</h3>
76
+ <span style=\{{ fontSize: '0.75rem', color: 'var(--fg-subtle)' }}>{p.role} · {p.year}</span>
77
+ </div>
78
+ <p style=\{{ color: 'var(--fg-muted)', fontSize: '0.875rem' }}>{p.summary}</p>
79
+ </Link>
80
+ </li>
81
+ ))}
82
+ </ul>
83
+ </section>
84
+ </div>
85
+ );
86
+ }
@@ -0,0 +1,8 @@
1
+ import type { NextConfig } from 'next';
2
+ import { withGitHat } from '@githat/nextjs/server';
3
+
4
+ const nextConfig: NextConfig = {
5
+ output: 'standalone',
6
+ };
7
+
8
+ export default withGitHat(nextConfig);
@@ -0,0 +1,14 @@
1
+ /*
2
+ * Plain template — Tailwind v4 PostCSS plugin is required even though
3
+ * the plain scaffold doesn't use Tailwind utility classes. The auth
4
+ * page CSS shipped by `@githat/nextjs/styles` is processed through
5
+ * @tailwindcss/postcss at build time. Drop this config and the
6
+ * auth pages render unstyled.
7
+ */
8
+ const config = {
9
+ plugins: {
10
+ '@tailwindcss/postcss': {},
11
+ },
12
+ };
13
+
14
+ export default config;
@@ -0,0 +1,10 @@
1
+ import { authProxy } from '@githat/nextjs/proxy';
2
+
3
+ export const proxy = authProxy({
4
+ publicRoutes: ['/', '/sign-in', '/sign-up'{{#if includeForgotPassword}}, '/forgot-password', '/reset-password'{{/if}}{{#if includeEmailVerification}}, '/verify-email'{{/if}}],
5
+ signInUrl: '/sign-in',
6
+ });
7
+
8
+ export const config = {
9
+ matcher: ['/((?!_next|api|.*\\..*).*)'],
10
+ };
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [{ "name": "next" }],
17
+ "paths": { "@/*": ["./*"] }
18
+ },
19
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
20
+ "exclude": ["node_modules"]
21
+ }
@@ -27,20 +27,22 @@ function NotFound() {
27
27
 
28
28
  export default function App() {
29
29
  return (
30
- <Routes>
31
- <Route path="/" element={<Home />} />
32
- <Route path="/sign-in" element={<SignIn />} />
33
- <Route path="/sign-up" element={<SignUp />} />
30
+ <>
31
+ <Routes>
32
+ <Route path="/" element={<Home />} />
33
+ <Route path="/sign-in" element={<SignIn />} />
34
+ <Route path="/sign-up" element={<SignUp />} />
34
35
  {{#if includeForgotPassword}}
35
- <Route path="/forgot-password" element={<ForgotPassword />} />
36
+ <Route path="/forgot-password" element={<ForgotPassword />} />
36
37
  {{/if}}
37
38
  {{#if includeEmailVerification}}
38
- <Route path="/verify-email" element={<VerifyEmail />} />
39
+ <Route path="/verify-email" element={<VerifyEmail />} />
39
40
  {{/if}}
40
41
  {{#if includeDashboard}}
41
- <Route path="/dashboard/*" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />
42
+ <Route path="/dashboard/*" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />
42
43
  {{/if}}
43
- <Route path="*" element={<NotFound />} />
44
- </Routes>
44
+ <Route path="*" element={<NotFound />} />
45
+ </Routes>
46
+ </>
45
47
  );
46
48
  }
@@ -1,3 +1,4 @@
1
+ @import "@githat/ui/tokens.css";
1
2
  {{#if useTailwind}}
2
3
  @import "tailwindcss";
3
4
  {{/if}}
@@ -9,9 +10,9 @@
9
10
  }
10
11
 
11
12
  body {
12
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
- background: #09090b;
14
- color: #fafafa;
13
+ font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
14
+ background: var(--bg, #09090b);
15
+ color: var(--fg, #fafafa);
15
16
  }
16
17
 
17
18
  a {
@@ -1,4 +1,5 @@
1
1
  import { SignInButton, SignUpButton } from '@githat/nextjs';
2
+ import { Wordmark } from '@githat/ui';
2
3
 
3
4
  const hasKey = !!import.meta.env.VITE_GITHAT_PUBLISHABLE_KEY;
4
5
 
@@ -6,9 +7,7 @@ function SetupGuide() {
6
7
  return (
7
8
  <main {{#if useTailwind}}className="flex flex-col items-center justify-center min-h-screen gap-8 bg-[#09090b] text-[#fafafa] px-6"{{else}}style=\{{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', gap: '2rem', background: '#09090b', color: '#fafafa', padding: '0 1.5rem' }}{{/if}}>
8
9
  <div {{#if useTailwind}}className="text-center"{{else}}style=\{{ textAlign: 'center' }}{{/if}}>
9
- <h1 {{#if useTailwind}}className="text-4xl font-bold mb-2"{{else}}style=\{{ fontSize: '2.5rem', fontWeight: 700, marginBottom: '0.5rem' }}{{/if}}>
10
- {{businessName}}
11
- </h1>
10
+ <Wordmark name="{{businessName}}" size="xl" />
12
11
  <p {{#if useTailwind}}className="text-zinc-400"{{else}}style=\{{ color: '#a1a1aa' }}{{/if}}>
13
12
  Get started in 3 steps
14
13
  </p>
@@ -58,9 +57,7 @@ export default function Home() {
58
57
 
59
58
  return (
60
59
  <main {{#if useTailwind}}className="flex flex-col items-center justify-center min-h-screen gap-6 bg-[#09090b] text-[#fafafa]"{{else}}style=\{{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', gap: '1.5rem', background: '#09090b', color: '#fafafa' }}{{/if}}>
61
- <h1 {{#if useTailwind}}className="text-4xl font-bold"{{else}}style=\{{ fontSize: '2.5rem', fontWeight: 700 }}{{/if}}>
62
- Welcome to {{businessName}}
63
- </h1>
60
+ <Wordmark name="{{businessName}}" size="xl" />
64
61
  <p {{#if useTailwind}}className="text-zinc-400 max-w-lg text-center"{{else}}style=\{{ color: '#a1a1aa', maxWidth: '32rem', textAlign: 'center' }}{{/if}}>
65
62
  {{description}}
66
63
  </p>
@@ -0,0 +1,9 @@
1
+ import { SignInForm } from '@githat/nextjs';
2
+
3
+ export default function SignInPage() {
4
+ return (
5
+ <main {{#if useTailwind}}className="flex items-center justify-center min-h-screen bg-[#09090b]"{{else}}style=\{{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#09090b' }}{{/if}}>
6
+ <SignInForm signUpUrl="/sign-up" {{#if includeForgotPassword}}forgotPasswordUrl="/forgot-password"{{/if}} />
7
+ </main>
8
+ );
9
+ }
@@ -0,0 +1,9 @@
1
+ import { SignUpForm } from '@githat/nextjs';
2
+
3
+ export default function SignUpPage() {
4
+ return (
5
+ <main {{#if useTailwind}}className="flex items-center justify-center min-h-screen bg-[#09090b]"{{else}}style=\{{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#09090b' }}{{/if}}>
6
+ <SignUpForm signInUrl="/sign-in" />
7
+ </main>
8
+ );
9
+ }