feat: install Sanity and Sanity Studio

This commit is contained in:
Dorian Niemiec 2024-11-08 09:43:04 +01:00
parent d5d27b85c5
commit b13a237b38
13 changed files with 9253 additions and 116 deletions

View file

@ -9,4 +9,7 @@ EMAIL_CONTACT_ADDRESS=
EMAIL_CONTACT_DEST= 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=

View 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

File diff suppressed because it is too large Load diff

View file

@ -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
View 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
View file

@ -0,0 +1,31 @@
"use client";
/**
* This configuration is used to for the Sanity Studio thats 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
View 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
View 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
View 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
View 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"
})
});

View 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"
}
]
}
]
};

View file

@ -0,0 +1,3 @@
import blog from "./blog";
export const schemaTypes = [blog];

11
sanity/structure.js Normal file
View 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())
)
]);