selbekk / sanity-intro

En workshop for folk som vil komme i gang med Sanity

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Introduksjon til Sanity

Dette er workshoppen for deg som er helt ny med Sanity. Her vil du lære å bygge skjemaer og litt om de forskjellige innholdstypene, og hvordan man kan bruke de for å bygge opp forskjellige dokumenter.

På slutten av workshoppen sitter du igjen med din helt egne portfolio-side med innebygget CMS, som er klar til å prodsettes! 🚀

Om workshoppen

🧑‍🎓 Forkunnskaper

For å komme i gang med utvikling i Sanity, er det greit å ha litt kjennskap til JavaScript eller TypeScript. Det er likevel helt mulig å få til workshoppen uten å være særlig godt kjent i språkene. ✨

Teknologier

Selve redaktørverktøyet er Sanity, som er tilgjengelig som et bibliotek vi bruker inne i frontend-appen.

Frontenden til portfolioen-appen er skrevet i React ⚛️ og NextJs 🔼 med app-folder. Der brukes NextUI 🧱 til noen av komponentene, og tailwindcss 🎨 til stilsetting.

For enkel kobling mellom Sanity og Next brukes Sanity.io toolkit for Next.js 🔧

🔤 Kom i gang!

📦 Kodekloning og avhengigheter

Før du kan begynne med selve workshoppen må vi laste ned prosjektet og installere litt avhengigheter.

  1. Du må å ha node installert.
  2. git clone prosjektet ned til din maskin
  3. Gå inn i prosjekt-mappen og innstallerer avhengighetene med npm install

👤 Lage seg konto og prosjekt på Sanity

  1. Først av alt må du gå på https://www.sanity.io/login/sign-up og lage deg en bruker. Det enkleste er kanskje å bruke github-brukeren din
  2. Her blir det litt hårete for å få satt opp prosjektet til rett bruker. Så her er det greit å ha tunga rett i munnen 👅.
  • Kjør npm -y create sanity@latest i prosjekt-mappa
  • Velg påloggingstypen du bruke for å registrere deg i steg 1, vent til den hopper inn i nettleseren og logger deg inn.
  • Gi prosjektet ditt et navn
  • Svar på følgende spørsmål:
Use the default dataset configuration?
Yes

Would you like to add configuration files for a Sanity project in this Next.js folder?
Yes

Do you want to use TypeScript?
Yes

Would you like an embedded Sanity Studio?
Yes

Would you like to use the Next.js app directory for routes?
Yes

What route do you want to use for the Studio?
/studio

File /app/studio/[[...index]]/page.tsx already exists. Do you want to overwrite it?
No

File /sanity.config.ts already exists. Do you want to overwrite it?
No

File /sanity.cli.ts already exists. Do you want to overwrite it?
No

Select project template to use
Clean project with no predefined schemas

File /sanity/schema.ts already exists. Do you want to overwrite it?
No

File /sanity/env.ts already exists. Do you want to overwrite it?
No

File /sanity/lib/client.ts already exists. Do you want to overwrite it?
No

File /sanity/lib/image.ts already exists. Do you want to overwrite it?
No

Would you like to add the project ID and dataset to your .env file?
Yes
  1. Og da skal du være klar til å starte appen med kommandoen npm run dev.
  • Appen starter opp på http://localhost:3000
  • Naviger deg fra forsiden inn til studioet.
  • Der vil du få forespørsel om å legge til CORS origin i Sanity prosjektet. Velg Continue
  • Du vil bli flyttet til Sanity sine sider. Velg Add CORS origin
  • Da, er du ferdig og klar! 👏✨

Oppgavene

Emojis 😺

Du kommer til å se noen emojis i oppgavene. De betyr ca det her:

  • 🏆 Oppgave: Her er hva du skal gjøre
  • 💡 Tips: Litt ekstra info som kan være greit å være for å løse en oppgave
  • ✅ Testing av løsningen: Hvordan du kan sjekke at det du har gjør blir riktig
  • 🚨 Løsningsforslag: Her finner du en komplett gjennomgang av hvordan du kan løse oppgaven

🧑‍💻 1. Legge til en forfatter!

Vi starter litt enkelt. Vi trenger å lage et dokument for en forfatter, for å så legge til litt data om oss selv.

For å lage dokumenter, må vi definere en schema for hvordan dataen ser ut. I Sanity har alle schemas noen spesifikke felter:

  • name som gir navn til et felt.
  • type som spesifiserer hvilke type skjema det skal være.
  • fields som er hvilke felter skjemaet skal inneholde.

For å registrere skjemaer må du importere det og legge det til i lista over forskjellige skjema-typer i /sanity/schema.ts

🏆 I filen /sanity/schemas/author.ts, kan du lage et dokument-type schema for author, som inneholder et felt name av typen string.

✅ For å se om det har blitt riktig kan du åpne Sanity studioet på http://localhost:3000/studio/. Det skal automatisk ha blitt lagt til en "mappe" for forfattere, hvor man kan trykke på 📝-ikonet for å lage et nytt dokument. Dette bør inneholde et enkelt input felt for å fylle inn navn på forfatteren.

💡 Vi får mye hjelp av TypeScript til å definere skjemaer.
Skjema-definisjoner kan types med SchemaTypeDefinition så får man feilmelding hvis man prøver å legge til noen attributter som ikke er gyldige!

💡 Du kan endre tittel og legge til en beskrivelse på felter med å legge til title og description på felter.

💡 NB: Selv om du kan lage flere forfatter-dokumenter, er frontenden konfigurert til å kun bruke det som var laget først hvis det er flere 🤠

🚨 Løsningforslag

I filen sanity/schemas/author.ts må vi fylle inn de grunnleggende feltene for dokument-skjemaet vårt i author-objektet. Fordi dette skal være et enkeltstående dokument vi kan hente data fra, så må det ha typen document.

Hvis man ønsker kan man gi det en tittel.

Alle dokumenter har en liste fields med hvilke felter dokumentet skal inneholde. Her må vi legge til en liste som inneholder et objekt som definerer name-feltet.

export const author: SchemaTypeDefinition = {
  name: "author",
  type: "document",
  title: "Forfatter",
  fields: [{ name: "name", title: "Navn", type: "string" }],
};

Alle skjema-typer må registreres slik at Sanity-studio vet at de eksisterer. Dette kan gjøres enkelt i sanity/schema.ts, ved å importere author fra underliggende mappen, og legge det til i arrayet med skjemaer.

export const schema: { types: SchemaTypeDefinition[] } = {
  types: [author],
};

🤹 2. Flere felter og flere felttyper!

Det finnes flere måter å vise felter på. string gir et helt standard lite input-felt å skrive i. Et alternativ for litt lengre tekster vil være å bruke typen text som gir et textarea-felt med muligheten til å justere størrelsen på input-feltet.

🏆 Legg til et felt bio av typen text på forfatter-objektet.

🏆 Juster samtidig bio feltet slik at det bare er 3 rader stort.

✅ Hvis alt blir riktig kan du se at det dukker opp et nytt felt på forfatter-dokumentet i studioet.

🚨 Løsningforslag

Her kan vi enkelt og greit legge til et nytt felt, men denne gangen med typen text. Man kan også legge på attributtet rows for å styre hvor mange rader feltet har når man åpner dokumentet.

i sanity/schemas/author.ts

export const author: SchemaTypeDefinition = {
  name: "author",
  type: "document",
  title: "Forfatter",
  fields: [
    { name: "name", title: "Navn", type: "string" },
    { name: "bio", title: "Biografi", type: "text", rows: 3 },
  ],
};

🚨 3. Valideringer

Det er fort gjort å gjøre feil! Derfor er det greit å legge på litt enkle valideringer som forhindrer oss å publisere feilaktig data.

En av de enkleste valideringene er å sette felt som påkrevd, men det finnes mange andre typer valideringsregler man også kan bruke rett ut av boksen. Det er også mulig å lage egne regler.

🏆 Lag en regel som gjør feltet name påkrevd

🏆 Lag en regel som gjør at feltet bio er både påkrevet og skal være mellom 30 og 160 tegn.

✅ Gi studioet en liten refresh ♻️. Hvis alt går som det skal vil du få en feilmelding i det du tømmer en av feltene. Feilmeldingene vil forhindre at dokumentet publiseres. Hvis det fungerer som det skal, er det bare å fylle ut feltene og publisere dokumentet. 🚀

Nå skal det begynne å dukke opp noe på forsiden av appen vår.

💡 Det er også nyttig å legge til description på felter og av og til hjelpetekst i valideringer.

🚨 Løsningforslag

Her må vi legge på validation på hvert av feltene våre. Denne tar inn en funksjon som tar i mot et rule-objekt man kan legge til valideringer på.

Her skal vi legge til henholdsvis (rule) => rule.required() for påkrevd og min(30) og max(160) for å styre antall tegn.

I sanity/schemas/author.ts

export const author: SchemaTypeDefinition = {
  name: "author",
  type: "document",
  title: "Forfatter",
  fields: [
    {
      name: "name",
      title: "Navn",
      type: "string",
      validation: (rule) => rule.required(),
    },
    {
      name: "bio",
      title: "Biografi",
      type: "text",
      rows: 3,
      validation: (rule) => rule.required().min(30).max(160),
    },
  ],
};

🪺 4. Nøstede felter

Det er også mulig å nøste felter sammen i objekter. Det er fint å benytte seg av når man begynner å få mange felter og det gir mening med en dypere struktur.

Vi skal nå utvide forsiden vår med litt lenker til forskjellige sosiale medier.

🏆 Lag et felt socials av typen object med underfelter github, twitter og linkedin som er lenker til forskjellige profiler.

💡 Hvis man skal bruke URL'er finnes det en egen felt-type url som automatisk validerer at det er i riktig format. 💡 Felter av typen object kan ta et felt options med collapsible og collapsed for å enkelt "lukke" objektet.

✅ Fyll ut feltene og publiser dokumentet på nytt. Forsiden skal nå ha lenker til de forskjellige feltene. Du trenger ikke fylle ut alle hvis du ikke bruker alle tjenestene. Feltene er tross alt ikke påkrevd.

🚨 Løsningforslag

Her må vi først legge til et felt av typen object. Deretter kan man legge på ytteligere fields inne i objektet.

Ved å bruke typen url på disse nøsta feltene, vil vi få validering ut av boksen.

Som en bonus kan man legge på optionene collapsible og collapsed for å gjøre feltet ekspanderbart, og lukket når man åpner dokumentet. Det er kanskje ikke nødvendig her, men på store dokumenter, er det ganske greit å holde det litt ryddig.

I sanity/schemas/author.ts

export const author: SchemaTypeDefinition = {
  name: "author",
  type: "document",
  title: "Forfatter",
  fields: [
    {
      name: "name",
      title: "Navn",
      type: "string",
      validation: (rule) => rule.required(),
    },
    {
      name: "bio",
      title: "Biografi",
      type: "text",
      rows: 3,
      validation: (rule) => rule.required().min(30).max(160),
    },
    {
      name: "socials",
      title: "Sosiale medier",
      type: "object",
      options: {
        collapsible: true,
        collapsed: true,
      },
      fields: [
        {
          name: "github",
          type: "url",
        },
        {
          name: "linkedin",
          type: "url",
        },
        {
          name: "twitter",
          type: "url",
        },
      ],
    },
  ],
};

🖼️ 5. Bilder

En av de aller beste måtene å presentere innhold på med er med bilder, og nå er det på tide å lage muligheten for å legge til et bilde av forfatteren.

Sanity har en egen type for bilder, og har et kraftig bildeverktøy for å generere lenker til forskjellige størrelser og varianter av et bilde som er lastet opp.

🏆 Legg inn et felt image for av bilde på forfatteren.

🏆 Lag støtte for å kunne sette en hotspot på bildet

✅ Legg inn et fint bilde. Gå over til forsiden igjen og se at det dukker opp istedenfor placeholder-bildet. Hvis bildet er litt rart croppa, kan du justere det med croppe-verktøyet oppe i høyre hjørnet av bilde-feltet. ✂️

🚨 Løsningforslag

Her legger vi til et felt av typen image. På det kan man legge til en option for hotspot for å gjøre det mulig å legge til croppe-muligheter.

I sanity/schemas/author.ts

export const author: SchemaTypeDefinition = {
  name: "author",
  type: "document",
  title: "Forfatter",
  fields: [
    {
      name: "name",
      title: "Navn",
      type: "string",
      validation: (rule) => rule.required(),
    },
    {
      name: "bio",
      title: "Biografi",
      type: "text",
      rows: 3,
      validation: (rule) => rule.required().min(30).max(160),
    },
    {
      name: "image",
      title: "Bilde",
      type: "image",
      options: {
        hotspot: true,
      },
    },
    {
      name: "socials",
      title: "Sosiale medier",
      type: "object",
      options: {
        collapsible: true,
        collapsed: true,
      },
      fields: [
        {
          name: "github",
          type: "url",
        },
        {
          name: "linkedin",
          type: "url",
        },
        {
          name: "twitter",
          type: "url",
        },
      ],
    },
  ],
};

💼 6. Prosjekter

Nok om oss selv 💅. Hele poenget med en portfolio er jo å vise frem litt prosjekter man har gjort! Nå er det på tide at vi går i gang med å lage dokument-skjemaet for prosjekter.

🏆 Lag dokumenttypen for prosjekter i /sanity/schemas/project.ts.

  • Et prosjektnavn som heter projectName
  • En slug 🐌 som heter slug
    • En slug er den siste delen av en URL. Her kunne vi ha brukt den innebygde skjulte feltet _id som ligger på dokumentet. Men det er mye mer SEO-vennlig med en lesbar og relevant URL.
  • En kort beskrivelse som heter shortDescription
  • En dato som heter date
  • Et bilde som heter image

🏆 Gjør alle feltene påkrevd

🏆 Legg til en knapp for automatisk slug-generering som bruker projectName feltet

🏆 Gi feltene noen bedre visningsnavn i studioet 🏷️

💡 Dokumentasjonen til skjema-typene forteller mye spennende om hvilke options man kan legge på de forskjellige type feltene.

💡 Unsplash har mange gode placeholder-bilder hvis man ikke har bilder til prosjektene sine.

✅ Fyll inn feltene og se om det dukker opp et prosjekt på forsiden. Se at det går an å trykke seg inn der!

🚨 Løsningforslag

Her går vi rett å slett i gang med å legge til feltene som trengs.

slug typen har en option som heter source som vil legge til muligheten for å generere en slug basert på sourcen

Feltene må inneholde en title for å få bedre visningsnavn.

Her må man også huske på å legge til den nye skjema-typen vår i sanity/schema.ts

I sanity/schemas/project.ts

export const project: SchemaTypeDefinition = {
  name: "project",
  title: "Prosjekter",
  type: "document",
  fields: [
    {
      name: "projectName",
      title: "Prosjektnavn",
      type: "string",
      validation: (rule) => rule.required(),
    },
    {
      name: "shortDescription",
      title: "En kort beskrivelse av prosjektet",
      type: "text",
      validation: (rule) => rule.required(),
    },
    {
      name: "slug",
      type: "slug",
      options: { source: "projectName" },
      validation: (rule) => rule.required(),
    },
    {
      name: "date",
      title: "Dato",
      type: "date",
    },
    {
      name: "image",
      title: "Prosjektbilde",
      type: "image",
      validation: (rule) => rule.required(),
    },
  ],
};

I sanity/schema.ts

export const schema: { types: SchemaTypeDefinition[] } = {
  types: [author, project],
};

🏷️ 7. Arrays og tags!

Vi ønsker å kunne tagge prosjektene våre med relevant nøkkelord. Siden vi har flere av disse, så passer det seg å ta i bruk array-typen. Man kan putte hva som helst i et array, men vi skal gå for noen enkle nøkkelord.

🏆 Legg til et felt keywords som er en liste av string

🏆 Endre layout til tags sånn at det blir enkelt å legge til tags.

🚨 Løsningforslag

I sanity/schemas/project.ts

export const project: SchemaTypeDefinition = {
  name: "project",
  title: "Prosjekter",
  type: "document",
  fields: [
    {
      name: "projectName",
      title: "Prosjektnavn",
      type: "string",
      validation: (rule) => rule.required(),
    },
    {
      name: "shortDescription",
      title: "En kort beskrivelse av prosjektet",
      type: "text",
      validation: (rule) => rule.required(),
    },
    {
      name: "slug",
      type: "slug",
      options: { source: "projectName" },
      validation: (rule) => rule.required(),
    },
    {
      name: "date",
      title: "Dato",
      type: "date",
    },
    {
      name: "keywords",
      title: "Nøkkelord",
      type: "array",
      of: [{ type: "string" }],
      options: {
        layout: "tags",
      },
    },
    {
      name: "image",
      title: "Prosjektbilde",
      type: "image",
      validation: (rule) => rule.required(),
    },
  ],
};

8. 💰 Riktekst innhold!

Vanlige string-baserte felter kan være litt begrensende hvis man skal produsere mye innhold til en side. En av superkreftene til Sanity er block content som gir en kraftig og tilpassningsvennlig WYSIWYG-editor.

Dette gjør det mulig å berike tekst med en eller annen form for markup. Som for eksempel å gjøre en tekst bold eller italic. Det gjør det også mulig å markere tekst som for eksempel headere (<h1>).

🏆 Legg til et felt content som er en riktekst editor.

✅ Prøv å fylle ut litt innhold om et prosjekt og publiser det. Innholdet vil dukke opp når du trykker inn på prosjektet.

🚨 Løsningforslag

I sanity har rik-tekst innhold typen block. Hvis man lager et array av typen block vil Sanity automatisk vise dette som et felt med riktekst.

I sanity/schemas/project.ts

export const project: SchemaTypeDefinition = {
  name: "project",
  title: "Prosjekter",
  type: "document",
  fields: [
    {
      name: "projectName",
      title: "Prosjektnavn",
      type: "string",
      validation: (rule) => rule.required(),
    },
    {
      name: "shortDescription",
      title: "En kort beskrivelse av prosjektet",
      type: "text",
      validation: (rule) => rule.required(),
    },
    {
      name: "slug",
      type: "slug",
      options: { source: "projectName" },
      validation: (rule) => rule.required(),
    },
    {
      name: "date",
      title: "Dato",
      type: "date",
    },
    {
      name: "keywords",
      title: "Nøkkelord",
      type: "array",
      of: [{ type: "string" }],
      options: {
        layout: "tags",
      },
    },
    {
      name: "image",
      title: "Prosjektbilde",
      type: "image",
      validation: (rule) => rule.required(),
    },
    {
      name: "content",
      title: "Content",
      type: "array",
      of: [
        {
          type: "block",
        },
      ],
    },
  ],
};

🦸 9. Utvide støtten i riktekst-editoren

Sanity er veldig konfigurerbart. Man kan både avgrense og utvide støtte for forskjellig markup i riktekst-editoren. Men i vår editor kan ikke bare være tekst i tekst-editoren 🤡. Vi ønsker nemlig å kunne bryte opp wall-of-text beskrivelsen av prosjektene med litt fine bilder.

🏆 Utvid rik-tekst editoren vår med støtte for en type image

💡 Riktekst er et array av block. Hva skjer om vi legger til andre ting også her?

✅ I riktekst-editoren vil det nå dukke opp en liten knapp i høyre hjørne for å legge til et bilde. Legg til et bilde, publiser, og sjekk at det dukker opp rett på prosjekt-siden.

🚨 Løsningforslag

Vi utvider hvilke typer som skal være tilgjengelige i arrayet og legger på et image

I sanity/schemas/project.ts

export const project: SchemaTypeDefinition = {
  name: "project",
  title: "Prosjekter",
  type: "document",
  fields: [
    {
      name: "projectName",
      title: "Prosjektnavn",
      type: "string",
      validation: (rule) => rule.required(),
    },
    {
      name: "shortDescription",
      title: "En kort beskrivelse av prosjektet",
      type: "text",
      validation: (rule) => rule.required(),
    },
    {
      name: "slug",
      type: "slug",
      options: { source: "projectName" },
      validation: (rule) => rule.required(),
    },
    {
      name: "date",
      title: "Dato",
      type: "date",
    },
    {
      name: "keywords",
      title: "Nøkkelord",
      type: "array",
      of: [{ type: "string" }],
      options: {
        layout: "tags",
      },
    },
    {
      name: "image",
      title: "Prosjektbilde",
      type: "image",
      validation: (rule) => rule.required(),
    },
    {
      name: "content",
      title: "Content",
      type: "array",
      of: [
        {
          type: "block",
        },
        {
          type: "image",
        },
      ],
    },
  ],
};

🎉 Ferdig!

Gratulerer! Da er du ferdig med portfolio-nettsiden 🤩.

Hvis du vil så kan du prøve å bryne deg på noen av ekstraoppgavene ⭐️


⭐️ Ekstraoppgaver

🚀 Ship-it!

Du kan rimelig enkelt putte appen din i produksjon! Vercel er en rask og enkel måte å deploye NextJs-apper på! Det du trenger å gjøre er å dytte koden til prosjektet ditt opp i et eget Github-repository og så koble Vercel på det.

Du må huske å konfigurere env-variablene for Sanity-tilgang på Vercel, samt å åpne opp for en ny CORS-policy hos Sanity

Det kan også være nyttig å justere på revalidate-intervallet som er satt i funksjonene for å hente data i /utils/author.ts og /utils/projects.ts. Sånn som det er satt opp nå vil den hente dataen for hver eneste besøkende på siden, men hvis det ikke endrer seg så ofte kan man godt skru denne opp. Du kan lese mer om data-henting, caching og revalidering på NextJs-dokumentasjonen

📝 Fylle ut noen prosjekter

Det nytter ikke å ha en flunkende ny portfolio-app uten innhold! Bruk litt tid på å fylle ut noen av prosjektene du har gjort tidligere.

🎨 Pynte litt på frontenden

Det er helt supert om du gjør frontenden din egen! Frontenden bruker NextUI og tailwindcss som gir både komponenter og en hel haug av stiler ut av boksen. Det er også veldig enkelt å justere ting hvis det er noe du ikke er fornøyd med.

❓ Kanskje det mangler noen felter?

Det går fint an å utvide med noen ekstra felter hvis man ønsker det. Spørringene for å hente ut data ligger i /utils/-mappa. De henter nå ut alle feltene som legges inn på dokumenter.

Hvis man vil se litt på mer avanserte måter å hente ut data, kan man sjekke ut query-språket til Sanity, som er groq.

About

En workshop for folk som vil komme i gang med Sanity


Languages

Language:TypeScript 97.4%Language:JavaScript 1.4%Language:CSS 1.2%