@tanstack/create 0.61.5 → 0.62.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.
- package/CHANGELOG.md +23 -0
- package/dist/config-file.js +5 -2
- package/dist/custom-add-ons/starter.js +45 -28
- package/dist/file-helpers.js +1 -0
- package/dist/frameworks/react/add-ons/shadcn/assets/src/styles.css +224 -15
- package/dist/frameworks/react/add-ons/store/assets/src/lib/demo-store.ts +5 -6
- package/dist/frameworks/react/add-ons/store/assets/src/routes/demo/store.tsx.ejs +1 -1
- package/dist/frameworks/react/add-ons/store/package.json +2 -2
- package/dist/frameworks/react/add-ons/strapi/README.md +158 -8
- package/dist/frameworks/react/add-ons/strapi/assets/_dot_env.local.append +1 -1
- package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/block-renderer.tsx +55 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/index.ts +14 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/media.tsx +27 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/quote.tsx +19 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/rich-text.tsx +11 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/slider.tsx +28 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/components/markdown-content.tsx +74 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/components/pagination.tsx +120 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/components/search.tsx +35 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/components/strapi-image.tsx +47 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/data/loaders/articles.ts +106 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/data/loaders/index.ts +28 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/data/strapi-sdk.ts +9 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/lib/strapi-utils.ts +25 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.$articleId.tsx +170 -0
- package/dist/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.tsx +269 -43
- package/dist/frameworks/react/add-ons/strapi/assets/src/types/strapi.ts +90 -0
- package/dist/frameworks/react/add-ons/strapi/info.json +3 -3
- package/dist/frameworks/react/add-ons/strapi/package.json +5 -2
- package/dist/frameworks/react/index.js +2 -2
- package/dist/frameworks/react/project/base/content/blog/fifth-post.mdx.ejs +54 -0
- package/dist/frameworks/react/project/base/content/blog/first-post.md.ejs +47 -0
- package/dist/frameworks/react/project/base/content/blog/fourth-post.md.ejs +42 -0
- package/dist/frameworks/react/project/base/content/blog/second-post.mdx.ejs +46 -0
- package/dist/frameworks/react/project/base/content/blog/third-post.md.ejs +49 -0
- package/dist/frameworks/react/project/base/content-collections.ts.ejs +37 -0
- package/dist/frameworks/react/project/base/package.json +8 -1
- package/dist/frameworks/react/project/base/public/images/lagoon-1.svg +13 -0
- package/dist/frameworks/react/project/base/public/images/lagoon-2.svg +12 -0
- package/dist/frameworks/react/project/base/public/images/lagoon-3.svg +12 -0
- package/dist/frameworks/react/project/base/public/images/lagoon-4.svg +12 -0
- package/dist/frameworks/react/project/base/public/images/lagoon-5.svg +12 -0
- package/dist/frameworks/react/project/base/public/images/lagoon-about.svg +14 -0
- package/dist/frameworks/react/project/base/src/components/Footer.tsx.ejs +42 -0
- package/dist/frameworks/react/project/base/src/components/Header.tsx.ejs +92 -138
- package/dist/frameworks/react/project/base/src/components/MdxCallout.tsx.ejs +16 -0
- package/dist/frameworks/react/project/base/src/components/MdxMetrics.tsx.ejs +23 -0
- package/dist/frameworks/react/project/base/src/components/ThemeToggle.tsx.ejs +81 -0
- package/dist/frameworks/react/project/base/src/lib/site.ts.ejs +4 -0
- package/dist/frameworks/react/project/base/src/main.tsx.ejs +0 -1
- package/dist/frameworks/react/project/base/src/routes/__root.tsx.ejs +10 -6
- package/dist/frameworks/react/project/base/src/routes/about.tsx.ejs +27 -0
- package/dist/frameworks/react/project/base/src/routes/blog.$slug.tsx.ejs +71 -0
- package/dist/frameworks/react/project/base/src/routes/blog.index.tsx.ejs +93 -0
- package/dist/frameworks/react/project/base/src/routes/index.tsx.ejs +58 -91
- package/dist/frameworks/react/project/base/src/routes/rss[.]xml.ts.ejs +35 -0
- package/dist/frameworks/react/project/base/src/styles.css.ejs +268 -6
- package/dist/frameworks/react/project/base/tsconfig.json.ejs +2 -0
- package/dist/frameworks/react/project/base/vite.config.ts.ejs +2 -0
- package/dist/frameworks/solid/add-ons/store/assets/src/lib/demo-store.ts +5 -6
- package/dist/frameworks/solid/add-ons/store/assets/src/routes/demo.store.tsx.ejs +2 -2
- package/dist/frameworks/solid/examples/tanchat/assets/src/lib/demo-store.ts +5 -6
- package/dist/frameworks/solid/project/base/src/components/Header.tsx.ejs +8 -6
- package/dist/frameworks/solid/project/base/src/routes/__root.tsx.ejs +1 -1
- package/dist/frameworks/solid/project/base/src/routes/index.tsx.ejs +1 -1
- package/dist/frameworks.js +3 -0
- package/dist/package-json.js +1 -1
- package/dist/registry.js +21 -4
- package/dist/types/registry.d.ts +38 -0
- package/package.json +1 -1
- package/src/config-file.ts +6 -2
- package/src/custom-add-ons/starter.ts +30 -10
- package/src/file-helpers.ts +1 -0
- package/src/frameworks/react/add-ons/shadcn/assets/src/styles.css +224 -15
- package/src/frameworks/react/add-ons/store/assets/src/lib/demo-store.ts +5 -6
- package/src/frameworks/react/add-ons/store/assets/src/routes/demo/store.tsx.ejs +1 -1
- package/src/frameworks/react/add-ons/store/package.json +2 -2
- package/src/frameworks/react/add-ons/strapi/README.md +158 -8
- package/src/frameworks/react/add-ons/strapi/assets/_dot_env.local.append +1 -1
- package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/block-renderer.tsx +55 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/index.ts +14 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/media.tsx +27 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/quote.tsx +19 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/rich-text.tsx +11 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/slider.tsx +28 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/components/markdown-content.tsx +74 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/components/pagination.tsx +120 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/components/search.tsx +35 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/components/strapi-image.tsx +47 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/data/loaders/articles.ts +106 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/data/loaders/index.ts +28 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/data/strapi-sdk.ts +9 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/lib/strapi-utils.ts +25 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.$articleId.tsx +170 -0
- package/src/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.tsx +269 -43
- package/src/frameworks/react/add-ons/strapi/assets/src/types/strapi.ts +90 -0
- package/src/frameworks/react/add-ons/strapi/info.json +3 -3
- package/src/frameworks/react/add-ons/strapi/package.json +5 -2
- package/src/frameworks/react/index.ts +2 -2
- package/src/frameworks/react/project/base/content/blog/fifth-post.mdx.ejs +54 -0
- package/src/frameworks/react/project/base/content/blog/first-post.md.ejs +47 -0
- package/src/frameworks/react/project/base/content/blog/fourth-post.md.ejs +42 -0
- package/src/frameworks/react/project/base/content/blog/second-post.mdx.ejs +46 -0
- package/src/frameworks/react/project/base/content/blog/third-post.md.ejs +49 -0
- package/src/frameworks/react/project/base/content-collections.ts.ejs +37 -0
- package/src/frameworks/react/project/base/package.json +8 -1
- package/src/frameworks/react/project/base/public/images/lagoon-1.svg +13 -0
- package/src/frameworks/react/project/base/public/images/lagoon-2.svg +12 -0
- package/src/frameworks/react/project/base/public/images/lagoon-3.svg +12 -0
- package/src/frameworks/react/project/base/public/images/lagoon-4.svg +12 -0
- package/src/frameworks/react/project/base/public/images/lagoon-5.svg +12 -0
- package/src/frameworks/react/project/base/public/images/lagoon-about.svg +14 -0
- package/src/frameworks/react/project/base/src/components/Footer.tsx.ejs +42 -0
- package/src/frameworks/react/project/base/src/components/Header.tsx.ejs +92 -138
- package/src/frameworks/react/project/base/src/components/MdxCallout.tsx.ejs +16 -0
- package/src/frameworks/react/project/base/src/components/MdxMetrics.tsx.ejs +23 -0
- package/src/frameworks/react/project/base/src/components/ThemeToggle.tsx.ejs +81 -0
- package/src/frameworks/react/project/base/src/lib/site.ts.ejs +4 -0
- package/src/frameworks/react/project/base/src/main.tsx.ejs +0 -1
- package/src/frameworks/react/project/base/src/routes/__root.tsx.ejs +10 -6
- package/src/frameworks/react/project/base/src/routes/about.tsx.ejs +27 -0
- package/src/frameworks/react/project/base/src/routes/blog.$slug.tsx.ejs +71 -0
- package/src/frameworks/react/project/base/src/routes/blog.index.tsx.ejs +93 -0
- package/src/frameworks/react/project/base/src/routes/index.tsx.ejs +58 -91
- package/src/frameworks/react/project/base/src/routes/rss[.]xml.ts.ejs +35 -0
- package/src/frameworks/react/project/base/src/styles.css.ejs +268 -6
- package/src/frameworks/react/project/base/tsconfig.json.ejs +2 -0
- package/src/frameworks/react/project/base/vite.config.ts.ejs +2 -0
- package/src/frameworks/solid/add-ons/store/assets/src/lib/demo-store.ts +5 -6
- package/src/frameworks/solid/add-ons/store/assets/src/routes/demo.store.tsx.ejs +2 -2
- package/src/frameworks/solid/examples/tanchat/assets/src/lib/demo-store.ts +5 -6
- package/src/frameworks/solid/project/base/src/components/Header.tsx.ejs +8 -6
- package/src/frameworks/solid/project/base/src/routes/__root.tsx.ejs +1 -1
- package/src/frameworks/solid/project/base/src/routes/index.tsx.ejs +1 -1
- package/src/frameworks.ts +4 -0
- package/src/package-json.ts +1 -1
- package/src/registry.ts +28 -4
- package/tests/add-ons.test.ts +4 -4
- package/tests/config-file.test.ts +3 -3
- package/tests/custom-add-ons/starter.test.ts +34 -2
- package/tests/frameworks.test.ts +24 -0
- package/tests/options.test.ts +4 -4
- package/tests/utils.test.ts +2 -2
- package/dist/frameworks/react/add-ons/strapi/assets/src/lib/strapiClient.ts +0 -7
- package/dist/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi_.$articleId.tsx +0 -78
- package/src/frameworks/react/add-ons/strapi/assets/src/lib/strapiClient.ts +0 -7
- package/src/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi_.$articleId.tsx +0 -78
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @tanstack/create
|
|
2
2
|
|
|
3
|
+
## 0.62.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- This release pulls together a large batch of improvements across the CLI and scaffolding engine since the last versioning pass. ([`154b25e`](https://github.com/TanStack/cli/commit/154b25eec9a13b9718c44cbed6cb3c8566f2fb11))
|
|
8
|
+
|
|
9
|
+
- Modernizes and refreshes the generated React/Solid template experience, including updated starter content and stronger defaults.
|
|
10
|
+
- Improves create flows with better option normalization, stronger guardrails around target directories, and clearer compatibility behavior in router-only mode.
|
|
11
|
+
- Expands scaffolding ergonomics with examples toggles, improved add-on/config handling, and reliability fixes across package-manager and cross-platform paths.
|
|
12
|
+
- Strengthens test and release confidence via e2e/release workflow hardening and broader smoke coverage.
|
|
13
|
+
- Streamlines product surface area by removing the local `create-ui` package and `--ui` command paths from the CLI; visual setup now lives at `https://tanstack.com/builder`.
|
|
14
|
+
- Cleans up docs and custom CLI examples to match the current terminal-first workflow and Builder guidance.
|
|
15
|
+
|
|
16
|
+
## 0.61.6
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Improve the Strapi add-on scaffolding for reliability. ([#323](https://github.com/TanStack/cli/pull/323))
|
|
21
|
+
|
|
22
|
+
- Remove brittle post-create shell automation that attempted to clone and bootstrap a sibling Strapi server.
|
|
23
|
+
- Fix Strapi article detail routing to use a consistent file-based route path.
|
|
24
|
+
- Update Strapi add-on guidance to document manual/hosted Strapi setup expectations.
|
|
25
|
+
|
|
3
26
|
## 0.61.5
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
package/dist/config-file.js
CHANGED
|
@@ -23,8 +23,8 @@ export async function readConfigFileFromEnvironment(environment, targetDir) {
|
|
|
23
23
|
const originalJSON = JSON.parse(config);
|
|
24
24
|
// Look for markers out outdated config files and upgrade the format on the fly (it will be written in the updated version after we add add-ons)
|
|
25
25
|
if (originalJSON.existingAddOns) {
|
|
26
|
-
if (originalJSON.framework === 'react') {
|
|
27
|
-
originalJSON.framework = 'react
|
|
26
|
+
if (originalJSON.framework === 'react-cra') {
|
|
27
|
+
originalJSON.framework = 'react';
|
|
28
28
|
}
|
|
29
29
|
originalJSON.chosenAddOns = originalJSON.existingAddOns;
|
|
30
30
|
delete originalJSON.existingAddOns;
|
|
@@ -35,6 +35,9 @@ export async function readConfigFileFromEnvironment(environment, targetDir) {
|
|
|
35
35
|
delete originalJSON.toolchain;
|
|
36
36
|
delete originalJSON.variableValues;
|
|
37
37
|
}
|
|
38
|
+
if (originalJSON.framework === 'react-cra') {
|
|
39
|
+
originalJSON.framework = 'react';
|
|
40
|
+
}
|
|
38
41
|
return originalJSON;
|
|
39
42
|
}
|
|
40
43
|
catch {
|
|
@@ -4,33 +4,37 @@ import { resolve } from 'node:path';
|
|
|
4
4
|
import { StarterCompiledSchema } from '../types.js';
|
|
5
5
|
import { createIgnore } from '../file-helpers.js';
|
|
6
6
|
import { compareFilesRecursively, createAppOptionsFromPersisted, createPackageAdditions, readCurrentProjectOptions, runCreateApp, } from './shared.js';
|
|
7
|
-
const INFO_FILE = '
|
|
8
|
-
const
|
|
7
|
+
const INFO_FILE = 'template-info.json';
|
|
8
|
+
const LEGACY_INFO_FILE = 'starter-info.json';
|
|
9
|
+
const COMPILED_FILE = 'template.json';
|
|
10
|
+
const LEGACY_COMPILED_FILE = 'starter.json';
|
|
9
11
|
export async function readOrGenerateStarterInfo(options) {
|
|
10
12
|
const info = existsSync(INFO_FILE)
|
|
11
13
|
? JSON.parse((await readFile(INFO_FILE)).toString())
|
|
12
|
-
:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
14
|
+
: existsSync(LEGACY_INFO_FILE)
|
|
15
|
+
? JSON.parse((await readFile(LEGACY_INFO_FILE)).toString())
|
|
16
|
+
: {
|
|
17
|
+
id: `${options.projectName}-template`,
|
|
18
|
+
name: `${options.projectName} Template`,
|
|
19
|
+
version: '0.0.1',
|
|
20
|
+
description: 'Project template',
|
|
21
|
+
author: 'Jane Smith <jane.smith@example.com>',
|
|
22
|
+
license: 'MIT',
|
|
23
|
+
link: `https://github.com/jane-smith/${options.projectName}-template`,
|
|
24
|
+
shadcnComponents: [],
|
|
25
|
+
framework: options.framework,
|
|
26
|
+
mode: options.mode,
|
|
27
|
+
routes: [],
|
|
28
|
+
warning: '',
|
|
29
|
+
type: 'starter',
|
|
30
|
+
packageAdditions: {
|
|
31
|
+
scripts: {},
|
|
32
|
+
dependencies: {},
|
|
33
|
+
devDependencies: {},
|
|
34
|
+
},
|
|
35
|
+
dependsOn: options.chosenAddOns,
|
|
36
|
+
typescript: true,
|
|
37
|
+
};
|
|
34
38
|
if (!info.version) {
|
|
35
39
|
info.version = '0.0.1';
|
|
36
40
|
}
|
|
@@ -44,8 +48,13 @@ async function loadCurrentStarterInfo(environment) {
|
|
|
44
48
|
}
|
|
45
49
|
export async function updateStarterInfo(environment) {
|
|
46
50
|
const { info, output } = await loadCurrentStarterInfo(environment);
|
|
47
|
-
|
|
51
|
+
const generatedPackageJson = output.files['./package.json'] ?? output.files['package.json'];
|
|
52
|
+
if (!generatedPackageJson) {
|
|
53
|
+
throw new Error('Unable to find generated package.json in template output');
|
|
54
|
+
}
|
|
55
|
+
info.packageAdditions = createPackageAdditions(JSON.parse(generatedPackageJson), JSON.parse((await readFile('package.json')).toString()));
|
|
48
56
|
writeFileSync(INFO_FILE, JSON.stringify(info, null, 2));
|
|
57
|
+
writeFileSync(LEGACY_INFO_FILE, JSON.stringify(info, null, 2));
|
|
49
58
|
}
|
|
50
59
|
export async function compileStarter(environment) {
|
|
51
60
|
const { info, output } = await loadCurrentStarterInfo(environment);
|
|
@@ -64,20 +73,28 @@ export async function compileStarter(environment) {
|
|
|
64
73
|
deletedFiles,
|
|
65
74
|
};
|
|
66
75
|
writeFileSync(COMPILED_FILE, JSON.stringify(compiledInfo, null, 2));
|
|
76
|
+
writeFileSync(LEGACY_COMPILED_FILE, JSON.stringify(compiledInfo, null, 2));
|
|
67
77
|
}
|
|
68
78
|
export async function initStarter(environment) {
|
|
69
79
|
await updateStarterInfo(environment);
|
|
70
80
|
await compileStarter(environment);
|
|
71
81
|
}
|
|
72
82
|
export async function loadStarter(url) {
|
|
73
|
-
const
|
|
74
|
-
const
|
|
83
|
+
const absoluteLocalPath = resolve(process.cwd(), url);
|
|
84
|
+
const localPath = existsSync(url)
|
|
85
|
+
? url
|
|
86
|
+
: existsSync(absoluteLocalPath)
|
|
87
|
+
? absoluteLocalPath
|
|
88
|
+
: undefined;
|
|
89
|
+
const jsonContent = localPath
|
|
90
|
+
? JSON.parse((await readFile(localPath)).toString())
|
|
91
|
+
: await (await fetch(url)).json();
|
|
75
92
|
const checked = StarterCompiledSchema.safeParse(jsonContent);
|
|
76
93
|
if (!checked.success) {
|
|
77
94
|
throw new Error(`Invalid starter: ${url}`);
|
|
78
95
|
}
|
|
79
96
|
const starter = checked.data;
|
|
80
|
-
starter.id = url;
|
|
97
|
+
starter.id = localPath ?? url;
|
|
81
98
|
return {
|
|
82
99
|
...starter,
|
|
83
100
|
getFiles: () => Promise.resolve(Object.keys(starter.files)),
|
package/dist/file-helpers.js
CHANGED
|
@@ -1,24 +1,32 @@
|
|
|
1
|
+
@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&family=Manrope:wght@400;500;600;700;800&display=swap');
|
|
1
2
|
@import 'tailwindcss';
|
|
3
|
+
@plugin '@tailwindcss/typography';
|
|
2
4
|
|
|
3
5
|
@import 'tw-animate-css';
|
|
4
6
|
|
|
5
7
|
@custom-variant dark (&:is(.dark *));
|
|
6
8
|
|
|
7
|
-
body {
|
|
8
|
-
@apply m-0;
|
|
9
|
-
font-family:
|
|
10
|
-
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
|
|
11
|
-
'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
|
12
|
-
-webkit-font-smoothing: antialiased;
|
|
13
|
-
-moz-osx-font-smoothing: grayscale;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
code {
|
|
17
|
-
font-family:
|
|
18
|
-
source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
9
|
:root {
|
|
10
|
+
--sea-ink: #173a40;
|
|
11
|
+
--sea-ink-soft: #416166;
|
|
12
|
+
--lagoon: #4fb8b2;
|
|
13
|
+
--lagoon-deep: #328f97;
|
|
14
|
+
--palm: #2f6a4a;
|
|
15
|
+
--sand: #e7f0e8;
|
|
16
|
+
--foam: #f3faf5;
|
|
17
|
+
--surface: rgba(255, 255, 255, 0.74);
|
|
18
|
+
--surface-strong: rgba(255, 255, 255, 0.9);
|
|
19
|
+
--line: rgba(23, 58, 64, 0.14);
|
|
20
|
+
--inset-glint: rgba(255, 255, 255, 0.82);
|
|
21
|
+
--kicker: rgba(47, 106, 74, 0.9);
|
|
22
|
+
--bg-base: #e7f3ec;
|
|
23
|
+
--header-bg: rgba(251, 255, 248, 0.84);
|
|
24
|
+
--chip-bg: rgba(255, 255, 255, 0.8);
|
|
25
|
+
--chip-line: rgba(47, 106, 74, 0.18);
|
|
26
|
+
--link-bg-hover: rgba(255, 255, 255, 0.9);
|
|
27
|
+
--hero-a: rgba(79, 184, 178, 0.36);
|
|
28
|
+
--hero-b: rgba(47, 106, 74, 0.2);
|
|
29
|
+
|
|
22
30
|
--background: oklch(1 0 0);
|
|
23
31
|
--foreground: oklch(0.141 0.005 285.823);
|
|
24
32
|
--card: oklch(1 0 0);
|
|
@@ -55,6 +63,26 @@ code {
|
|
|
55
63
|
}
|
|
56
64
|
|
|
57
65
|
.dark {
|
|
66
|
+
--sea-ink: #d7ece8;
|
|
67
|
+
--sea-ink-soft: #afcdc8;
|
|
68
|
+
--lagoon: #60d7cf;
|
|
69
|
+
--lagoon-deep: #8de5db;
|
|
70
|
+
--palm: #6ec89a;
|
|
71
|
+
--sand: #0f1a1e;
|
|
72
|
+
--foam: #101d22;
|
|
73
|
+
--surface: rgba(16, 30, 34, 0.8);
|
|
74
|
+
--surface-strong: rgba(15, 27, 31, 0.92);
|
|
75
|
+
--line: rgba(141, 229, 219, 0.18);
|
|
76
|
+
--inset-glint: rgba(194, 247, 238, 0.14);
|
|
77
|
+
--kicker: #b8efe5;
|
|
78
|
+
--bg-base: #0a1418;
|
|
79
|
+
--header-bg: rgba(10, 20, 24, 0.8);
|
|
80
|
+
--chip-bg: rgba(13, 28, 32, 0.9);
|
|
81
|
+
--chip-line: rgba(141, 229, 219, 0.24);
|
|
82
|
+
--link-bg-hover: rgba(24, 44, 49, 0.8);
|
|
83
|
+
--hero-a: rgba(96, 215, 207, 0.18);
|
|
84
|
+
--hero-b: rgba(110, 200, 154, 0.12);
|
|
85
|
+
|
|
58
86
|
--background: oklch(0.141 0.005 285.823);
|
|
59
87
|
--foreground: oklch(0.985 0 0);
|
|
60
88
|
--card: oklch(0.141 0.005 285.823);
|
|
@@ -90,6 +118,7 @@ code {
|
|
|
90
118
|
}
|
|
91
119
|
|
|
92
120
|
@theme inline {
|
|
121
|
+
--font-sans: 'Manrope', ui-sans-serif, system-ui, sans-serif;
|
|
93
122
|
--color-background: var(--background);
|
|
94
123
|
--color-foreground: var(--foreground);
|
|
95
124
|
--color-card: var(--card);
|
|
@@ -128,11 +157,191 @@ code {
|
|
|
128
157
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
129
158
|
}
|
|
130
159
|
|
|
160
|
+
html,
|
|
161
|
+
body,
|
|
162
|
+
#app {
|
|
163
|
+
min-height: 100%;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
body {
|
|
167
|
+
margin: 0;
|
|
168
|
+
color: var(--sea-ink);
|
|
169
|
+
font-family: var(--font-sans);
|
|
170
|
+
background-color: var(--bg-base);
|
|
171
|
+
background:
|
|
172
|
+
radial-gradient(1100px 620px at -8% -10%, var(--hero-a), transparent 58%),
|
|
173
|
+
radial-gradient(1050px 620px at 112% -12%, var(--hero-b), transparent 62%),
|
|
174
|
+
radial-gradient(720px 380px at 50% 115%, rgba(79, 184, 178, 0.1), transparent 68%),
|
|
175
|
+
linear-gradient(180deg, color-mix(in oklab, var(--sand) 68%, white) 0%, var(--foam) 44%, var(--bg-base) 100%);
|
|
176
|
+
overflow-x: hidden;
|
|
177
|
+
-webkit-font-smoothing: antialiased;
|
|
178
|
+
-moz-osx-font-smoothing: grayscale;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
body::before {
|
|
182
|
+
content: '';
|
|
183
|
+
position: fixed;
|
|
184
|
+
inset: 0;
|
|
185
|
+
pointer-events: none;
|
|
186
|
+
z-index: -1;
|
|
187
|
+
opacity: 0.28;
|
|
188
|
+
background:
|
|
189
|
+
radial-gradient(circle at 20% 15%, rgba(255, 255, 255, 0.8), transparent 34%),
|
|
190
|
+
radial-gradient(circle at 78% 26%, rgba(79, 184, 178, 0.2), transparent 42%),
|
|
191
|
+
radial-gradient(circle at 42% 82%, rgba(47, 106, 74, 0.14), transparent 36%);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
body::after {
|
|
195
|
+
content: '';
|
|
196
|
+
position: fixed;
|
|
197
|
+
inset: 0;
|
|
198
|
+
pointer-events: none;
|
|
199
|
+
z-index: -1;
|
|
200
|
+
opacity: 0.14;
|
|
201
|
+
background-image:
|
|
202
|
+
linear-gradient(rgba(255, 255, 255, 0.07) 1px, transparent 1px),
|
|
203
|
+
linear-gradient(90deg, rgba(255, 255, 255, 0.06) 1px, transparent 1px);
|
|
204
|
+
background-size: 28px 28px;
|
|
205
|
+
mask-image: radial-gradient(circle at 50% 30%, black, transparent 78%);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
a {
|
|
209
|
+
color: var(--lagoon-deep);
|
|
210
|
+
text-decoration-color: rgba(50, 143, 151, 0.4);
|
|
211
|
+
text-decoration-thickness: 1px;
|
|
212
|
+
text-underline-offset: 2px;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
a:hover {
|
|
216
|
+
color: #246f76;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
code {
|
|
220
|
+
font-size: 0.9em;
|
|
221
|
+
border: 1px solid var(--line);
|
|
222
|
+
background: color-mix(in oklab, var(--surface-strong) 82%, white 18%);
|
|
223
|
+
border-radius: 7px;
|
|
224
|
+
padding: 2px 7px;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
pre code {
|
|
228
|
+
border: 0;
|
|
229
|
+
background: transparent;
|
|
230
|
+
padding: 0;
|
|
231
|
+
border-radius: 0;
|
|
232
|
+
font-size: inherit;
|
|
233
|
+
color: inherit;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.prose pre {
|
|
237
|
+
border: 1px solid var(--line);
|
|
238
|
+
border-radius: 12px;
|
|
239
|
+
background: #1d2e45;
|
|
240
|
+
color: #e8efff;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.page-wrap {
|
|
244
|
+
width: min(1080px, calc(100% - 2rem));
|
|
245
|
+
margin-inline: auto;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.display-title {
|
|
249
|
+
font-family: 'Fraunces', Georgia, serif;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.island-shell {
|
|
253
|
+
border: 1px solid var(--line);
|
|
254
|
+
background: linear-gradient(165deg, var(--surface-strong), var(--surface));
|
|
255
|
+
box-shadow:
|
|
256
|
+
0 1px 0 var(--inset-glint) inset,
|
|
257
|
+
0 22px 44px rgba(30, 90, 72, 0.1),
|
|
258
|
+
0 6px 18px rgba(23, 58, 64, 0.08);
|
|
259
|
+
backdrop-filter: blur(4px);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.feature-card {
|
|
263
|
+
background: linear-gradient(165deg, color-mix(in oklab, var(--surface-strong) 93%, white 7%), var(--surface));
|
|
264
|
+
box-shadow:
|
|
265
|
+
0 1px 0 var(--inset-glint) inset,
|
|
266
|
+
0 18px 34px rgba(30, 90, 72, 0.1),
|
|
267
|
+
0 4px 14px rgba(23, 58, 64, 0.06);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.feature-card:hover {
|
|
271
|
+
transform: translateY(-2px);
|
|
272
|
+
border-color: color-mix(in oklab, var(--lagoon-deep) 35%, var(--line));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
button,
|
|
276
|
+
.island-shell,
|
|
277
|
+
a {
|
|
278
|
+
transition: background-color 180ms ease, color 180ms ease, border-color 180ms ease,
|
|
279
|
+
transform 180ms ease;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.island-kicker {
|
|
283
|
+
letter-spacing: 0.16em;
|
|
284
|
+
text-transform: uppercase;
|
|
285
|
+
font-weight: 700;
|
|
286
|
+
font-size: 0.69rem;
|
|
287
|
+
color: var(--kicker);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.nav-link {
|
|
291
|
+
position: relative;
|
|
292
|
+
text-decoration: none;
|
|
293
|
+
color: var(--sea-ink-soft);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.nav-link::after {
|
|
297
|
+
content: '';
|
|
298
|
+
position: absolute;
|
|
299
|
+
left: 0;
|
|
300
|
+
bottom: -8px;
|
|
301
|
+
width: 100%;
|
|
302
|
+
height: 2px;
|
|
303
|
+
transform: scaleX(0);
|
|
304
|
+
transform-origin: left;
|
|
305
|
+
background: linear-gradient(90deg, var(--lagoon), #7ed3bf);
|
|
306
|
+
transition: transform 170ms ease;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.nav-link:hover,
|
|
310
|
+
.nav-link.is-active {
|
|
311
|
+
color: var(--sea-ink);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.nav-link:hover::after,
|
|
315
|
+
.nav-link.is-active::after {
|
|
316
|
+
transform: scaleX(1);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.rise-in {
|
|
320
|
+
animation: rise-in 700ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
@keyframes rise-in {
|
|
324
|
+
from {
|
|
325
|
+
opacity: 0;
|
|
326
|
+
transform: translateY(12px);
|
|
327
|
+
}
|
|
328
|
+
to {
|
|
329
|
+
opacity: 1;
|
|
330
|
+
transform: translateY(0);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.site-footer {
|
|
335
|
+
border-top: 1px solid var(--line);
|
|
336
|
+
background: color-mix(in oklab, var(--header-bg) 84%, transparent 16%);
|
|
337
|
+
}
|
|
338
|
+
|
|
131
339
|
@layer base {
|
|
132
340
|
* {
|
|
133
341
|
@apply border-border outline-ring/50;
|
|
134
342
|
}
|
|
135
343
|
body {
|
|
136
|
-
|
|
344
|
+
background-color: var(--background);
|
|
345
|
+
color: var(--foreground);
|
|
137
346
|
}
|
|
138
347
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Store } from '@tanstack/store'
|
|
2
2
|
|
|
3
3
|
export const store = new Store({
|
|
4
4
|
firstName: 'Jane',
|
|
5
5
|
lastName: 'Smith',
|
|
6
6
|
})
|
|
7
7
|
|
|
8
|
-
export const fullName = new
|
|
9
|
-
fn: () => `${store.state.firstName} ${store.state.lastName}`,
|
|
10
|
-
deps: [store],
|
|
11
|
-
})
|
|
8
|
+
export const fullName = new Store(`${store.state.firstName} ${store.state.lastName}`)
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
store.subscribe(() => {
|
|
11
|
+
fullName.setState(() => `${store.state.firstName} ${store.state.lastName}`)
|
|
12
|
+
})
|
|
@@ -1,14 +1,164 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Strapi CMS Integration
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This add-on integrates Strapi CMS with your TanStack Start application using the official Strapi Client SDK.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Features
|
|
6
6
|
|
|
7
|
+
- Article listing with search and pagination
|
|
8
|
+
- Article detail pages with dynamic block rendering
|
|
9
|
+
- Rich text, quotes, media, and image slider blocks
|
|
10
|
+
- Markdown content rendering with GitHub Flavored Markdown
|
|
11
|
+
- Responsive image handling with error fallbacks
|
|
12
|
+
- URL-based search and pagination (shareable/bookmarkable)
|
|
13
|
+
- Graceful error handling with helpful setup instructions
|
|
14
|
+
|
|
15
|
+
### Project Structure
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
parent/
|
|
19
|
+
├── client/ # TanStack Start frontend (your project name)
|
|
20
|
+
│ ├── src/
|
|
21
|
+
│ │ ├── components/
|
|
22
|
+
│ │ │ ├── blocks/ # Block rendering components
|
|
23
|
+
│ │ │ ├── markdown-content.tsx
|
|
24
|
+
│ │ │ ├── pagination.tsx
|
|
25
|
+
│ │ │ ├── search.tsx
|
|
26
|
+
│ │ │ └── strapi-image.tsx
|
|
27
|
+
│ │ ├── data/
|
|
28
|
+
│ │ │ ├── loaders/ # Server functions
|
|
29
|
+
│ │ │ └── strapi-sdk.ts
|
|
30
|
+
│ │ ├── lib/
|
|
31
|
+
│ │ │ └── strapi-utils.ts
|
|
32
|
+
│ │ ├── routes/demo/
|
|
33
|
+
│ │ │ ├── strapi.tsx # Articles list
|
|
34
|
+
│ │ │ └── strapi.$articleId.tsx # Article detail
|
|
35
|
+
│ │ └── types/
|
|
36
|
+
│ │ └── strapi.ts
|
|
37
|
+
│ ├── .env.local
|
|
38
|
+
│ └── package.json
|
|
39
|
+
└── server/ # Strapi CMS backend (create manually or use hosted Strapi)
|
|
40
|
+
├── src/api/ # Content types
|
|
41
|
+
├── config/ # Strapi configuration
|
|
42
|
+
└── package.json
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Quick Start
|
|
46
|
+
|
|
47
|
+
Create your Strapi project separately (or use an existing hosted Strapi instance), then point this app to it with `VITE_STRAPI_URL`.
|
|
48
|
+
|
|
49
|
+
**1. Set up Strapi:**
|
|
50
|
+
|
|
51
|
+
Follow the Strapi quick-start guide to create a local project, or use your existing Strapi deployment:
|
|
52
|
+
|
|
53
|
+
- https://docs.strapi.io/dev-docs/quick-start
|
|
54
|
+
|
|
55
|
+
If you created a local Strapi project in a sibling `server` directory, continue with:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cd ../server
|
|
59
|
+
npm install # or pnpm install / yarn install
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**2. Start the Strapi server:**
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm run develop # Starts at http://localhost:1337
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**3. Create an admin account:**
|
|
69
|
+
|
|
70
|
+
Open http://localhost:1337/admin and create your first admin user.
|
|
71
|
+
|
|
72
|
+
**4. Create content:**
|
|
73
|
+
|
|
74
|
+
In the Strapi admin panel, go to Content Manager > Article and create some articles.
|
|
75
|
+
|
|
76
|
+
**5. Start your TanStack app (in another terminal):**
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cd ../client # or your project name
|
|
80
|
+
npm run dev # Starts at http://localhost:3000
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**6. View the demo:**
|
|
84
|
+
|
|
85
|
+
Navigate to http://localhost:3000/demo/strapi to see your articles.
|
|
86
|
+
|
|
87
|
+
### Environment Variables
|
|
88
|
+
|
|
89
|
+
The following environment variable is pre-configured in `.env.local`:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
VITE_STRAPI_URL="http://localhost:1337"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
For production, update this to your deployed Strapi URL.
|
|
96
|
+
|
|
97
|
+
### Demo Pages
|
|
98
|
+
|
|
99
|
+
| URL | Description |
|
|
100
|
+
|-----|-------------|
|
|
101
|
+
| `/demo/strapi` | Articles list with search and pagination |
|
|
102
|
+
| `/demo/strapi/:articleId` | Article detail with block rendering |
|
|
103
|
+
|
|
104
|
+
### Search and Pagination
|
|
105
|
+
|
|
106
|
+
- **Search**: Type in the search box to filter articles by title or description
|
|
107
|
+
- **Pagination**: Navigate between pages using the pagination controls
|
|
108
|
+
- **URL State**: Search and page are stored in the URL (`?query=term&page=2`)
|
|
109
|
+
|
|
110
|
+
### Block Types Supported
|
|
111
|
+
|
|
112
|
+
| Block | Component | Description |
|
|
113
|
+
|-------|-----------|-------------|
|
|
114
|
+
| `shared.rich-text` | RichText | Markdown content |
|
|
115
|
+
| `shared.quote` | Quote | Blockquote with author |
|
|
116
|
+
| `shared.media` | Media | Single image/video |
|
|
117
|
+
| `shared.slider` | Slider | Image gallery grid |
|
|
118
|
+
|
|
119
|
+
### Dependencies
|
|
120
|
+
|
|
121
|
+
| Package | Purpose |
|
|
122
|
+
|---------|---------|
|
|
123
|
+
| `@strapi/client` | Official Strapi SDK |
|
|
124
|
+
| `react-markdown` | Markdown rendering |
|
|
125
|
+
| `remark-gfm` | GitHub Flavored Markdown |
|
|
126
|
+
| `use-debounce` | Debounced search input |
|
|
127
|
+
|
|
128
|
+
### Running Both Servers
|
|
129
|
+
|
|
130
|
+
Open two terminal windows from the parent directory:
|
|
131
|
+
|
|
132
|
+
**Terminal 1 - Strapi:**
|
|
7
133
|
```bash
|
|
8
|
-
|
|
9
|
-
cd my-strapi-project
|
|
10
|
-
pnpm dev
|
|
134
|
+
cd server && npm run develop
|
|
11
135
|
```
|
|
12
136
|
|
|
13
|
-
|
|
14
|
-
|
|
137
|
+
**Terminal 2 - TanStack Start:**
|
|
138
|
+
```bash
|
|
139
|
+
cd client && npm run dev # or your project name
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Customization
|
|
143
|
+
|
|
144
|
+
**Change page size:**
|
|
145
|
+
Edit `src/data/loaders/articles.ts` and modify `PAGE_SIZE`.
|
|
146
|
+
|
|
147
|
+
**Add new block types:**
|
|
148
|
+
1. Create component in `src/components/blocks/`
|
|
149
|
+
2. Export from `src/components/blocks/index.ts`
|
|
150
|
+
3. Add case to `block-renderer.tsx` switch statement
|
|
151
|
+
4. Update populate in articles loader
|
|
152
|
+
|
|
153
|
+
**Add new content types:**
|
|
154
|
+
1. Add types to `src/types/strapi.ts`
|
|
155
|
+
2. Create loader in `src/data/loaders/`
|
|
156
|
+
3. Create route in `src/routes/demo/`
|
|
157
|
+
|
|
158
|
+
### Learn More
|
|
159
|
+
|
|
160
|
+
- [Strapi Documentation](https://docs.strapi.io/)
|
|
161
|
+
- [Strapi Client SDK](https://www.npmjs.com/package/@strapi/client)
|
|
162
|
+
- [Strapi Cloud Template Blog](https://github.com/strapi/strapi-cloud-template-blog)
|
|
163
|
+
- [TanStack Start Documentation](https://tanstack.com/start/latest)
|
|
164
|
+
- [TanStack Router Search Params](https://tanstack.com/router/latest/docs/framework/react/guide/search-params)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# Strapi configuration
|
|
2
|
-
VITE_STRAPI_URL="http://localhost:1337
|
|
2
|
+
VITE_STRAPI_URL="http://localhost:1337"
|