feat: install Sanity and Sanity Studio
This commit is contained in:
parent
d5d27b85c5
commit
b13a237b38
13 changed files with 9253 additions and 116 deletions
|
@ -10,3 +10,6 @@ EMAIL_CONTACT_DEST=
|
||||||
|
|
||||||
NEXT_PUBLIC_HCAPTCHA_SITE_KEY=
|
NEXT_PUBLIC_HCAPTCHA_SITE_KEY=
|
||||||
HCAPTCHA_SECRET=
|
HCAPTCHA_SECRET=
|
||||||
|
|
||||||
|
NEXT_PUBLIC_SANITY_PROJECT_ID=
|
||||||
|
NEXT_PUBLIC_SANITY_DATASET=
|
19
app/studio/[[...tool]]/page.jsx
Normal file
19
app/studio/[[...tool]]/page.jsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* This route is responsible for the built-in authoring environment using Sanity Studio.
|
||||||
|
* All routes under your studio path is handled by this file using Next.js' catch-all routes:
|
||||||
|
* https://nextjs.org/docs/routing/dynamic-routes#catch-all-routes
|
||||||
|
*
|
||||||
|
* You can learn more about the next-sanity package here:
|
||||||
|
* https://github.com/sanity-io/next-sanity
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NextStudio } from "next-sanity/studio";
|
||||||
|
import config from "../../../sanity.config";
|
||||||
|
|
||||||
|
export const dynamic = "force-static";
|
||||||
|
|
||||||
|
export { metadata, viewport } from "next-sanity/studio";
|
||||||
|
|
||||||
|
export default function StudioPage() {
|
||||||
|
return <NextStudio config={config} />;
|
||||||
|
}
|
9194
package-lock.json
generated
9194
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -13,10 +13,15 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hcaptcha/react-hcaptcha": "^1.11.0",
|
"@hcaptcha/react-hcaptcha": "^1.11.0",
|
||||||
|
"@sanity/code-input": "^4.1.4",
|
||||||
|
"@sanity/icons": "^3.4.0",
|
||||||
|
"@sanity/image-url": "^1.1.0",
|
||||||
|
"@sanity/vision": "^3.63.0",
|
||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.15",
|
||||||
"globby": "^14.0.2",
|
"globby": "^14.0.2",
|
||||||
"lucide-react": "^0.454.0",
|
"lucide-react": "^0.454.0",
|
||||||
"next": "^15.0.2",
|
"next": "^15.0.2",
|
||||||
|
"next-sanity": "^9.8.10",
|
||||||
"next-themes": "^0.4.3",
|
"next-themes": "^0.4.3",
|
||||||
"nodemailer": "^6.9.16",
|
"nodemailer": "^6.9.16",
|
||||||
"prismjs": "^1.29.0",
|
"prismjs": "^1.29.0",
|
||||||
|
@ -25,6 +30,8 @@
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-markdown": "^9.0.1",
|
"react-markdown": "^9.0.1",
|
||||||
"rehype-prism": "^2.3.3",
|
"rehype-prism": "^2.3.3",
|
||||||
|
"sanity": "^3.63.0",
|
||||||
|
"styled-components": "^6.1.13",
|
||||||
"validator": "^13.12.0"
|
"validator": "^13.12.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
10
sanity.cli.js
Normal file
10
sanity.cli.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/**
|
||||||
|
* This configuration file lets you run `$ sanity [command]` in this folder
|
||||||
|
* Go to https://www.sanity.io/docs/cli to learn more.
|
||||||
|
**/
|
||||||
|
import { defineCliConfig } from "sanity/cli";
|
||||||
|
|
||||||
|
const projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID;
|
||||||
|
const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET;
|
||||||
|
|
||||||
|
export default defineCliConfig({ api: { projectId, dataset } });
|
31
sanity.config.js
Normal file
31
sanity.config.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This configuration is used to for the Sanity Studio that’s mounted on the `/app/studio/[[...tool]]/page.jsx` route
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { visionTool } from "@sanity/vision";
|
||||||
|
import { defineConfig } from "sanity";
|
||||||
|
import { structureTool } from "sanity/structure";
|
||||||
|
import { codeInput } from "@sanity/code-input";
|
||||||
|
|
||||||
|
// Go to https://www.sanity.io/docs/api-versioning to learn how API versioning works
|
||||||
|
import { apiVersion, dataset, projectId } from "./sanity/env";
|
||||||
|
import { schemaTypes } from "./sanity/schemaTypes";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
basePath: "/studio",
|
||||||
|
projectId,
|
||||||
|
dataset,
|
||||||
|
// Add and edit the content schema in the './sanity/schemaTypes' folder
|
||||||
|
schema: {
|
||||||
|
types: schemaTypes
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
structureTool(),
|
||||||
|
// Vision is for querying with GROQ from inside the Studio
|
||||||
|
// https://www.sanity.io/docs/the-vision-plugin
|
||||||
|
visionTool({ defaultApiVersion: apiVersion }),
|
||||||
|
codeInput()
|
||||||
|
]
|
||||||
|
});
|
5
sanity/env.js
Normal file
5
sanity/env.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export const apiVersion =
|
||||||
|
process.env.NEXT_PUBLIC_SANITY_API_VERSION || "2024-11-08";
|
||||||
|
|
||||||
|
export const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET;
|
||||||
|
export const projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID;
|
10
sanity/lib/client.js
Normal file
10
sanity/lib/client.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { createClient } from "next-sanity";
|
||||||
|
|
||||||
|
import { apiVersion, dataset, projectId } from "../env";
|
||||||
|
|
||||||
|
export const client = createClient({
|
||||||
|
projectId,
|
||||||
|
dataset,
|
||||||
|
apiVersion,
|
||||||
|
useCdn: true // Set to false if statically generating pages, using ISR or tag-based revalidation
|
||||||
|
});
|
10
sanity/lib/image.js
Normal file
10
sanity/lib/image.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import createImageUrlBuilder from "@sanity/image-url";
|
||||||
|
|
||||||
|
import { dataset, projectId } from "../env";
|
||||||
|
|
||||||
|
// https://www.sanity.io/docs/image-url
|
||||||
|
const builder = createImageUrlBuilder({ projectId, dataset });
|
||||||
|
|
||||||
|
export const urlFor = (source) => {
|
||||||
|
return builder.image(source);
|
||||||
|
};
|
13
sanity/lib/live.js
Normal file
13
sanity/lib/live.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Querying with "sanityFetch" will keep content automatically updated
|
||||||
|
// Before using it, import and render "<SanityLive />" in your layout, see
|
||||||
|
// https://github.com/sanity-io/next-sanity#live-content-api for more information.
|
||||||
|
import { defineLive } from "next-sanity";
|
||||||
|
import { client } from "./client";
|
||||||
|
|
||||||
|
export const { sanityFetch, SanityLive } = defineLive({
|
||||||
|
client: client.withConfig({
|
||||||
|
// Live content is currently only available on the experimental API
|
||||||
|
// https://www.sanity.io/docs/api-versioning
|
||||||
|
apiVersion: "vX"
|
||||||
|
})
|
||||||
|
});
|
51
sanity/schemaTypes/blog.js
Normal file
51
sanity/schemaTypes/blog.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
export default {
|
||||||
|
name: "blog",
|
||||||
|
type: "document",
|
||||||
|
title: "Blog",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "title",
|
||||||
|
type: "string",
|
||||||
|
title: "Title"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "slug",
|
||||||
|
type: "slug",
|
||||||
|
title: "Slug Title",
|
||||||
|
options: {
|
||||||
|
source: "title"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "titleImage",
|
||||||
|
type: "image",
|
||||||
|
title: "Title Image"
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// name: 'publishedAt',
|
||||||
|
// title: 'Published At',
|
||||||
|
// type: 'datetime',
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
name: "smallDescription",
|
||||||
|
type: "text",
|
||||||
|
title: "Small Description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "content",
|
||||||
|
type: "array",
|
||||||
|
title: "Content",
|
||||||
|
of: [
|
||||||
|
{
|
||||||
|
type: "block"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "image"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "code"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
3
sanity/schemaTypes/index.js
Normal file
3
sanity/schemaTypes/index.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import blog from "./blog";
|
||||||
|
|
||||||
|
export const schemaTypes = [blog];
|
11
sanity/structure.js
Normal file
11
sanity/structure.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// https://www.sanity.io/docs/structure-builder-cheat-sheet
|
||||||
|
export const structure = (S) =>
|
||||||
|
S.list()
|
||||||
|
.title("Blog")
|
||||||
|
.items([
|
||||||
|
S.documentTypeListItem("blog").title("Posts"),
|
||||||
|
S.divider(),
|
||||||
|
...S.documentTypeListItems().filter(
|
||||||
|
(item) => item.getId() && !["blog"].includes(item.getId())
|
||||||
|
)
|
||||||
|
]);
|
Loading…
Reference in a new issue