[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation":3,"url-settings":86,"blog-\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs":671,"blog-author-\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs":1688,"i-material-symbols:arrow-back-rounded":1700},{"id":4,"extension":5,"footer":6,"header":73,"meta":83,"stem":84,"__hash__":85},"navigation\u002Fdata\u002Fshared\u002Fnavigation.yml","yml",{"brand":7,"columns":13,"legal":63},{"name":8,"tagline":9,"downloadCta":10},"Pieces","The memory layer for modern work.",{"label":11,"href":12},"All downloads","\u002Fdownloads",[14,26,39,51],{"title":15,"links":16},"Product",[17,20,23],{"label":18,"href":19},"Pieces Desktop","\u002F",{"label":21,"href":22},"Pieces Enterprise","\u002Fenterprise",{"label":24,"href":25},"Pieces MCP","\u002Fmcp",{"title":27,"links":28},"Resources",[29,33,36],{"label":30,"href":31,"external":32},"Documentation","url:docs.home",true,{"label":34,"href":35},"Blog","\u002Fblog",{"label":37,"href":38,"external":32},"GitHub","url:github.org",{"title":40,"links":41},"Community",[42,45,48],{"label":43,"href":44,"external":32},"Discord","url:social.discord",{"label":46,"href":47,"external":32},"X \u002F Twitter","url:social.x",{"label":49,"href":50,"external":32},"LinkedIn","url:social.linkedin",{"title":52,"links":53},"Company",[54,57,60],{"label":55,"href":56},"About","\u002Fabout",{"label":58,"href":59},"Updates","\u002Fupdates",{"label":61,"href":62},"Contact","\u002Fcontact",[64,67,70],{"label":65,"href":66},"Privacy Policy","\u002Flegal\u002Fprivacy",{"label":68,"href":69},"Refund Policy","\u002Flegal\u002Frefund",{"label":71,"href":72},"Terms of Service","\u002Flegal\u002Fterms",{"links":74,"signIn":75,"contact":78,"cta":80},[],{"label":76,"href":77},"Manage account","url:portal.home",{"label":79,"href":62},"Get in touch",{"label":81,"href":82},"Download","url:routes.downloads",{},"data\u002Fshared\u002Fnavigation","XlSALC7vYCXHcmcXnjJViwIZKsqnQWF4bn4o9RrcSBE",{"id":87,"extension":5,"links":88,"meta":668,"stem":669,"__hash__":670},"urlSettings\u002Fdata\u002Fshared\u002Furls.yml",[89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,181,185,189,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256,260,264,268,272,276,280,284,288,292,296,300,303,307,311,314,318,322,326,330,334,338,342,346,350,354,358,362,366,370,374,378,382,386,390,394,398,402,406,410,414,418,422,426,430,434,438,442,446,450,454,458,461,465,469,473,477,481,485,488,491,494,497,501,505,508,512,516,520,524,528,532,536,540,544,548,552,556,559,563,567,571,575,579,582,585,588,592,595,599,603,607,611,614,618,622,625,628,631,635,639,643,646,649,652,656,660,664],{"key":90,"label":91,"href":92},"downloads.desktop","Desktop download page","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fdownload",{"key":94,"label":95,"href":96},"downloads.macOS.dmgArm64","macOS DMG Apple Silicon","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fpieces_for_x\u002Fdmg-arm64\u002Fdownload",{"key":98,"label":99,"href":100},"downloads.macOS.dmgIntel","macOS DMG Intel","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fpieces_for_x\u002Fdmg\u002Fdownload",{"key":102,"label":103,"href":104},"downloads.macOS.pkg","macOS PKG","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fmacos_packaging\u002Fpkg\u002Fdownload",{"key":106,"label":107,"href":108},"downloads.macOS.universal","Desktop macOS Universal","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fpieces_for_x\u002Fmacos-universal\u002Fdownload",{"key":110,"label":111,"href":112},"downloads.macOS.pkgArm64","Desktop macOS PKG Apple Silicon","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fmacos_packaging\u002Fpkg-pfd-arm64\u002Fdownload",{"key":114,"label":115,"href":116},"downloads.macOS.pkgIntel","Desktop macOS PKG Intel","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fmacos_packaging\u002Fpkg-pfd\u002Fdownload",{"key":118,"label":119,"href":120},"downloads.windows.appinstaller","Windows App Installer","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fappinstaller\u002Fpieces_for_x.appinstaller",{"key":122,"label":123,"href":124},"downloads.windows.exe","Windows EXE","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fpieces_for_x\u002Fwindows-exe\u002Fdownload",{"key":126,"label":127,"href":128},"downloads.windows.msix","Windows MSIX","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fpieces_for_x\u002Fwindows-msix\u002Fdownload",{"key":130,"label":131,"href":132},"downloads.windows.suiteManager","Windows Suite Manager","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fpieces_suite_windows\u002Fappinstaller\u002Fdownload",{"key":134,"label":135,"href":136},"downloads.linux.flatpakRepo","Linux Flatpak repository","https:\u002F\u002Fbuilds.pieces.app\u002Fpieces-flatpak-repo\u002Fpieces-flatpak.flatpakrepo",{"key":138,"label":139,"href":140},"downloads.linux.snapDesktop","Linux Snap Desktop","https:\u002F\u002Fsnapcraft.io\u002Fpieces-for-developers",{"key":142,"label":143,"href":144},"downloads.linux.snapPiecesOS","Linux Snap PiecesOS","https:\u002F\u002Fsnapcraft.io\u002Fpieces-os",{"key":146,"label":147,"href":148},"downloads.linux.snap","Desktop Linux Snap package","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fpieces_for_x\u002Fsnap\u002Fdownload",{"key":150,"label":151,"href":152},"downloads.piecesOS.macOS.dmgArm64","PiecesOS macOS DMG Apple Silicon","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fos_server\u002Fdmg-arm64\u002Fdownload",{"key":154,"label":155,"href":156},"downloads.piecesOS.macOS.dmgIntel","PiecesOS macOS DMG Intel","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fos_server\u002Fdmg\u002Fdownload",{"key":158,"label":159,"href":160},"downloads.piecesOS.macOS.universal","PiecesOS macOS Universal","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fos_server\u002Fmacos-universal\u002Fdownload",{"key":162,"label":163,"href":164},"downloads.piecesOS.macOS.pkgArm64","PiecesOS macOS PKG Apple Silicon","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fmacos_packaging\u002Fpkg-pos-launch-only-arm64\u002Fdownload",{"key":166,"label":167,"href":168},"downloads.piecesOS.macOS.pkgIntel","PiecesOS macOS PKG Intel","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fmacos_packaging\u002Fpkg-pos-launch-only\u002Fdownload",{"key":170,"label":171,"href":172},"downloads.piecesOS.windows.appinstaller","PiecesOS Windows App Installer","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fappinstaller\u002Fos_server.appinstaller",{"key":174,"label":175,"href":176},"downloads.piecesOS.windows.exe","PiecesOS Windows EXE","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fos_server\u002Fwindows-exe\u002Fdownload",{"key":178,"label":179,"href":180},"downloads.piecesOS.windows.msix","PiecesOS Windows MSIX","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fos_server\u002Fwindows-msix\u002Fdownload",{"key":182,"label":183,"href":184},"downloads.piecesOS.linux.snap","PiecesOS Linux Snap package","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fos_server\u002Fsnap\u002Fdownload",{"key":186,"label":187,"href":188},"downloads.combined.macOS.appleSilicon","Combined macOS installer Apple Silicon","https:\u002F\u002Fbuilds.pieces.app\u002Fstages\u002Fproduction\u002Fmacos_packaging\u002Fpkg-arm64\u002Fdownload",{"key":190,"label":191,"href":104},"downloads.combined.macOS.intel","Combined macOS installer Intel",{"key":193,"label":194,"href":195},"downloads.guides.macOS","macOS installation guide","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Fmacos-installation-guide",{"key":197,"label":198,"href":199},"downloads.guides.windows","Windows installation guide","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Fwindows-installation-guide",{"key":201,"label":202,"href":203},"downloads.guides.linux","Linux installation guide","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Flinux-installation-guide",{"key":205,"label":206,"href":207},"downloads.guides.linuxFlatpak","Linux Flatpak installation guide","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Flinux-installation-guide\u002Fflatpak",{"key":209,"label":210,"href":211},"downloads.guides.linuxSnap","Linux Snap installation guide","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Flinux-installation-guide\u002Fsnap",{"key":213,"label":214,"href":215},"downloads.guides.piecesOS","PiecesOS manual installation","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies\u002Fpieces-os\u002Fmanual-installation",{"key":217,"label":218,"href":219},"extensions.chrome","Chrome extension","https:\u002F\u002Fchrome.google.com\u002Fwebstore\u002Fdetail\u002Fpieces-save-code-snippets\u002Figbgibhbfonhmjlechmeefimncpekepm",{"key":221,"label":222,"href":223},"extensions.firefox","Firefox add-on","https:\u002F\u002Faddons.mozilla.org\u002Fen-US\u002Ffirefox\u002Faddon\u002Fpieces-save-code-from-the-web\u002F",{"key":225,"label":226,"href":227},"extensions.edge","Edge add-on","https:\u002F\u002Fmicrosoftedge.microsoft.com\u002Faddons\u002Fdetail\u002Fpieces-save-code-snippet\u002Fhglfimcdgonaeeobjckfdabcldfidmim",{"key":229,"label":230,"href":231},"extensions.vscode","VS Code extension","https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=MeshIntelligentTechnologiesInc.pieces-vscode",{"key":233,"label":234,"href":235},"extensions.visualStudio","Visual Studio extension","https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=MeshIntelligentTechnologiesInc.PiecesVisualStudio",{"key":237,"label":238,"href":239},"extensions.jetbrains","JetBrains plugin","https:\u002F\u002Fplugins.jetbrains.com\u002Fplugin\u002F17328-pieces--save-search-share--reuse-code-snippets",{"key":241,"label":242,"href":243},"extensions.obsidian","Obsidian plugin","https:\u002F\u002Fobsidian.md\u002Fplugins?id=pieces-for-developers",{"key":245,"label":246,"href":247},"extensions.sublime","Sublime package","https:\u002F\u002Fpackagecontrol.io\u002Fpackages\u002FPieces",{"key":249,"label":250,"href":251},"extensions.neovim","Neovim plugin","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fplugin_neo_vim",{"key":253,"label":254,"href":255},"extensions.jupyterlab","JupyterLab plugin","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fjupyterlab-pieces",{"key":257,"label":258,"href":259},"extensions.cli","Pieces CLI","https:\u002F\u002Fpypi.org\u002Fproject\u002Fpieces-cli\u002F",{"key":261,"label":262,"href":263},"docs.home","Documentation home","https:\u002F\u002Fdocs.pieces.app",{"key":265,"label":266,"href":267},"docs.getStarted","Get started docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces",{"key":269,"label":270,"href":271},"docs.api","API docs","https:\u002F\u002Fdocs.pieces.app\u002Fapi",{"key":273,"label":274,"href":275},"docs.desktop.overview","Desktop overview","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop",{"key":277,"label":278,"href":279},"docs.desktop.onboarding","Desktop onboarding","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fonboarding",{"key":281,"label":282,"href":283},"docs.desktop.timeline","Desktop timeline docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Ftimeline",{"key":285,"label":286,"href":287},"docs.desktop.summaries","Desktop summaries docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fsingle-click-summaries",{"key":289,"label":290,"href":291},"docs.desktop.search","Desktop conversational search docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fconversational-search",{"key":293,"label":294,"href":295},"docs.desktop.drive","Desktop drive docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fdrive",{"key":297,"label":298,"href":299},"docs.desktop.account","Desktop account settings docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fconfiguration\u002Faccount",{"key":301,"label":302,"href":92},"docs.desktop.download","Desktop download docs",{"key":304,"label":305,"href":306},"docs.piecesOS.overview","PiecesOS overview docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies",{"key":308,"label":309,"href":310},"docs.piecesOS.details","PiecesOS details docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies\u002Fpieces-os",{"key":312,"label":313,"href":215},"docs.piecesOS.install","PiecesOS install docs",{"key":315,"label":316,"href":317},"docs.piecesOS.quickMenu","PiecesOS quick menu docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies\u002Fpieces-os\u002Fquick-menu",{"key":319,"label":320,"href":321},"docs.piecesOS.storage","On-device storage docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies\u002Fon-device-storage",{"key":323,"label":324,"href":325},"docs.piecesOS.troubleshooting","PiecesOS troubleshooting docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies\u002Fpieces-os\u002Ftroubleshooting",{"key":327,"label":328,"href":329},"docs.mcp.overview","MCP overview docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp",{"key":331,"label":332,"href":333},"docs.mcp.cursor","MCP Cursor docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fcursor",{"key":335,"label":336,"href":337},"docs.mcp.vscode","MCP VS Code docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fvs-code",{"key":339,"label":340,"href":341},"docs.mcp.claudeDesktop","MCP Claude Desktop docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fclaude-desktop",{"key":343,"label":344,"href":345},"docs.mcp.claudeCode","MCP Claude Code docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fclaude-code",{"key":347,"label":348,"href":349},"docs.mcp.claudeCowork","MCP Claude Cowork docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fclaude-cowork",{"key":351,"label":352,"href":353},"docs.mcp.githubCopilot","MCP GitHub Copilot docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fgithub-copilot",{"key":355,"label":356,"href":357},"docs.mcp.goose","MCP Goose docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fgoose",{"key":359,"label":360,"href":361},"docs.mcp.windsurf","MCP Windsurf docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fwindsurf",{"key":363,"label":364,"href":365},"docs.mcp.zed","MCP Zed docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fzed",{"key":367,"label":368,"href":369},"docs.mcp.jetbrains","MCP JetBrains docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fjetbrains-ides",{"key":371,"label":372,"href":373},"docs.mcp.continueDev","MCP Continue docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fcontinue-dev",{"key":375,"label":376,"href":377},"docs.mcp.cline","MCP Cline docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fcline",{"key":379,"label":380,"href":381},"docs.mcp.raycast","MCP Raycast docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fraycast",{"key":383,"label":384,"href":385},"docs.mcp.rovoDevCli","MCP Rovo Dev CLI docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Frovo-dev-cli",{"key":387,"label":388,"href":389},"docs.mcp.openaiCodexCli","MCP OpenAI Codex CLI docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fopenai-codex-cli",{"key":391,"label":392,"href":393},"docs.mcp.googleGeminiCli","MCP Google Gemini CLI docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fgoogle-gemini-cli",{"key":395,"label":396,"href":397},"docs.mcp.amazonQ","MCP Amazon Q docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Famazon-q-developer",{"key":399,"label":400,"href":401},"docs.mcp.chatgptDev","MCP ChatGPT Developer Mode docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fchatgpt-developer-mode",{"key":403,"label":404,"href":405},"docs.mcp.openclaw","MCP OpenClaw docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fopenclaw",{"key":407,"label":408,"href":409},"docs.mcp.mcpRemote","MCP Remote docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fmcp-remote",{"key":411,"label":412,"href":413},"docs.mcp.ngrok","MCP ngrok docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fngrok-setup",{"key":415,"label":416,"href":417},"docs.troubleshooting.macOS","macOS troubleshooting docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Ftroubleshooting\u002Fmacos",{"key":419,"label":420,"href":421},"docs.troubleshooting.windows","Windows troubleshooting docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Ftroubleshooting\u002Fwindows",{"key":423,"label":424,"href":425},"docs.troubleshooting.linux","Linux troubleshooting docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Ftroubleshooting\u002Flinux",{"key":427,"label":428,"href":429},"docs.privacy","Privacy and security docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fprivacy-security-your-data",{"key":431,"label":432,"href":433},"docs.support","Support docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fsupport",{"key":435,"label":436,"href":437},"portal.home","Pieces portal","https:\u002F\u002Fportal.pieces.app",{"key":439,"label":440,"href":441},"site.home","Website home","https:\u002F\u002Fpieces.app",{"key":443,"label":444,"href":445},"site.about","About page","https:\u002F\u002Fpieces.app\u002Fabout",{"key":447,"label":448,"href":449},"site.features","Features page","https:\u002F\u002Fpieces.app\u002Ffeatures",{"key":451,"label":452,"href":453},"site.plugins","Plugins page","https:\u002F\u002Fpieces.app\u002Fplugins",{"key":455,"label":456,"href":457},"site.contact","Contact page","https:\u002F\u002Fpieces.app\u002Fcontact",{"key":459,"label":58,"href":460},"site.updates","https:\u002F\u002Fpieces.app\u002Fupdates",{"key":462,"label":463,"href":464},"site.news","News","https:\u002F\u002Fpieces.app\u002Fnews",{"key":466,"label":467,"href":468},"site.events","Community events","https:\u002F\u002Fpieces.app\u002Fcommunity\u002Fevents",{"key":470,"label":471,"href":472},"site.userStories","User stories","https:\u002F\u002Fpieces.app\u002Fuser-stories",{"key":474,"label":475,"href":476},"site.academy","Academy","https:\u002F\u002Fpieces.app\u002Flearn\u002Facademy",{"key":478,"label":479,"href":480},"site.support","Website support","https:\u002F\u002Fpieces.app\u002Fsupport",{"key":482,"label":483,"href":484},"site.standup","Standup","https:\u002F\u002Fpieces.app\u002Fstandup",{"key":486,"label":34,"href":487},"site.blog","https:\u002F\u002Fcode.pieces.app\u002Fblog",{"key":489,"label":43,"href":490},"social.discord","https:\u002F\u002Fdiscord.gg\u002Fgetpieces",{"key":492,"label":46,"href":493},"social.x","https:\u002F\u002Fx.com\u002Fgetpieces",{"key":495,"label":496,"href":493},"social.twitter","Twitter",{"key":498,"label":499,"href":500},"social.instagram","Instagram","https:\u002F\u002Fwww.instagram.com\u002Fgetpieces\u002F",{"key":502,"label":503,"href":504},"social.tiktok","TikTok","https:\u002F\u002Fwww.tiktok.com\u002F@getpieces",{"key":506,"label":49,"href":507},"social.linkedin","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fgetpieces\u002F",{"key":509,"label":510,"href":511},"social.youtube","YouTube","https:\u002F\u002Fyoutube.com\u002F@getpieces",{"key":513,"label":514,"href":515},"github.org","GitHub organization","https:\u002F\u002Fgithub.com\u002Fpieces-app",{"key":517,"label":518,"href":519},"github.support","GitHub support","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fsupport",{"key":521,"label":522,"href":523},"github.issues","GitHub issues","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fsupport\u002Fissues",{"key":525,"label":526,"href":527},"github.discussions","GitHub discussions","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fsupport\u002Fdiscussions",{"key":529,"label":530,"href":531},"github.documentation","GitHub documentation","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fdocumentation",{"key":533,"label":534,"href":535},"github.opensource","GitHub open source","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fopensource",{"key":537,"label":538,"href":539},"github.sdks.python","Python SDK","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fpieces-os-client-sdk-for-python",{"key":541,"label":542,"href":543},"github.sdks.typescript","TypeScript SDK","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fpieces-os-client-sdk-for-typescript",{"key":545,"label":546,"href":547},"github.sdks.dart","Dart SDK","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fpieces-os-client-sdk-for-dart",{"key":549,"label":550,"href":551},"github.sdks.kotlin","Kotlin SDK","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fpieces-os-client-sdk-for-kotlin",{"key":553,"label":554,"href":555},"github.plugins.obsidian","Obsidian plugin repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fobsidian-pieces",{"key":557,"label":558,"href":255},"github.plugins.jupyterlab","JupyterLab plugin repository",{"key":560,"label":561,"href":562},"github.plugins.sublime","Sublime plugin repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fplugin_sublime",{"key":564,"label":565,"href":566},"github.plugins.neovim","Neovim plugin repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fplugin_neovim",{"key":568,"label":569,"href":570},"github.cliAgent","CLI agent repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fcli-agent",{"key":572,"label":573,"href":574},"github.mcpDart","MCP Dart repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fmcp_dart",{"key":576,"label":577,"href":578},"github.awesomePieces","Awesome Pieces repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fawesome-pieces",{"key":580,"label":581,"href":66},"legal.privacyPolicy","Privacy policy",{"key":583,"label":584,"href":69},"legal.refundPolicy","Refund policy",{"key":586,"label":587,"href":72},"legal.terms","Terms",{"key":589,"label":590,"href":591},"legal.security","Legal security","https:\u002F\u002Fpieces.app\u002Flegal\u002Fsecurity",{"key":593,"label":594,"href":511},"videos.youtubeChannel","YouTube channel",{"key":596,"label":597,"href":598},"videos.gettingStartedDesktop","Getting started desktop video","https:\u002F\u002Fyoutu.be\u002FdUr1lRM_TYk",{"key":600,"label":601,"href":602},"videos.snippetDiscoveryxR","Snippet discovery video","https:\u002F\u002Fyoutu.be\u002FG6vb1USw-30",{"key":604,"label":605,"href":606},"sales.bookACall","Book a sales call","https:\u002F\u002Fcalendar.app.google\u002FWVUDtUfNy5Vst3sH7",{"key":608,"label":609,"href":610},"sales.enterprise","Enterprise form","https:\u002F\u002Fgetpieces.typeform.com\u002Fto\u002FaVQFTvpE",{"key":612,"label":613,"href":527},"sales.feedback","Feedback discussions",{"key":615,"label":616,"href":617},"sales.earlyAccess","Early access form","https:\u002F\u002Fgetpieces.typeform.com\u002Fearlyaccess",{"key":619,"label":620,"href":621},"sales.supportEmail","Support email","mailto:support@pieces.app",{"key":623,"label":624,"href":19},"routes.home","Home route",{"key":626,"label":627,"href":56},"routes.about","About route",{"key":629,"label":630,"href":12},"routes.downloads","Downloads route",{"key":632,"label":633,"href":634},"routes.thanks","Post-install thanks route","\u002Finstall\u002Fthanks",{"key":636,"label":637,"href":638},"routes.pricing","Pricing route","\u002Fpricing",{"key":640,"label":641,"href":642},"cta.freeTrial","Start free trial CTA (Pieces Pro) — used by \u002Fcampaigns\u002F* landing pages","https:\u002F\u002Fcampaigns.pieces.app\u002F",{"key":644,"label":645,"href":22},"routes.enterprise","Enterprise route",{"key":647,"label":648,"href":62},"routes.contact","Contact route",{"key":650,"label":651,"href":59},"routes.updates","Updates route",{"key":653,"label":654,"href":655},"routes.migrationError","Migration error route","\u002Fmigration\u002Ferror",{"key":657,"label":658,"href":659},"routes.authenticated","Post-login authenticated route","\u002Fauth\u002Fsigned-in",{"key":661,"label":662,"href":663},"routes.signed-out","Signed out route","\u002Fauth\u002Fsigned-out",{"key":665,"label":666,"href":667},"routes.authentication-error","Authentication error route","\u002Fauth\u002Ferror",{},"data\u002Fshared\u002Furls","2AvfSWI6bZACH5Kr1ZS3txMLjteRjCjbDR_ul1uRZ9Q",{"id":672,"title":673,"author":674,"authorPhoto":675,"authorPhotoAlt":676,"authorSlug":677,"body":678,"buttonText":676,"buttonUrl":676,"category":1676,"date":1677,"description":1678,"draft":1679,"editorsPick":1679,"extension":1680,"featured":1679,"image":1681,"imageAlt":1682,"meta":1683,"navigation":32,"ogImage":676,"ogImageAlt":676,"path":1684,"seo":1685,"stem":1686,"tags":676,"__hash__":1687},"blog\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs.md","How to Create Sanity Headless CMS in Next.js","Sage Osoro","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Funderstanding-structs-and-enums-in-solidity\u002Fauthor.png",null,"sage-osoro",{"type":679,"value":680,"toc":1658},"minimark",[681,686,702,716,719,724,733,737,740,745,748,752,755,783,786,790,799,810,817,820,826,832,835,842,845,851,854,860,863,868,871,877,880,895,899,902,908,914,917,923,926,930,933,939,945,952,958,964,982,988,994,1004,1010,1016,1020,1045,1051,1057,1060,1066,1072,1085,1091,1097,1104,1110,1113,1117,1120,1126,1132,1147,1153,1159,1177,1183,1189,1192,1198,1204,1211,1217,1223,1232,1238,1244,1249,1255,1261,1264,1270,1276,1285,1291,1297,1300,1306,1312,1315,1321,1324,1328,1342,1348,1354,1364,1370,1376,1382,1388,1394,1397,1403,1409,1412,1418,1424,1427,1433,1439,1446,1452,1458,1467,1473,1479,1482,1488,1494,1508,1514,1520,1526,1532,1538,1541,1547,1553,1556,1562,1568,1581,1587,1593,1600,1606,1612,1622,1628,1634,1637,1643,1646,1650],[682,683,685],"h2",{"id":684},"what-is-sanityio","What is Sanity.io?",[687,688,689,696,697,701],"p",{},[690,691,695],"a",{"href":692,"rel":693},"https:\u002F\u002Fwww.sanity.io\u002F",[694],"nofollow","Sanity.io"," is a unified content platform where you can store and manage content for a website or application. Unlike traditional ",[698,699,700],"strong",{},"Content Management Systems"," (CMS) like WordPress or Wix, which keep your content and display it on the front-end for you, Sanity headless CMS stores your content but lets you decide how you want that content to be displayed. With Sanity.io, you can show your content on different web and mobile applications.",[687,703,704,709,710,715],{},[690,705,708],{"href":706,"rel":707},"https:\u002F\u002Fnextjs.org\u002F",[694],"Next.js",", a framework that seamlessly integrates with Sanity.io, proves to be an excellent choice for leveraging the platform's capabilities. Next.js is a popular React framework used by developers to render React applications server-side to improve Search Engine Optimization (SEO) performance. Foundation is a great ",[690,711,714],{"href":712,"rel":713},"https:\u002F\u002Fpieces.app\u002Fblog\u002Ffoundation-the-best-framework-for-building-responsive-sites",[694],"framework for building responsive sites"," as well.",[687,717,718],{},"In this tutorial, We will go through how you can create text, images, and other media types with Sanity.io and display that content in your Next.js application.",[687,720,721],{},[698,722,723],{},"Prerequisites",[687,725,726,727,732],{},"This tutorial assumes that you have a basic understanding of how Sanity Content Management Systems (CMS) and Sanity Next.js work. Learn more about ",[690,728,731],{"href":729,"rel":730},"https:\u002F\u002Fmedium.com\u002F@sageosoro\u002Fwhy-you-should-use-next-js-in-all-your-react-projects-a8e634bba4b4",[694],"why you should use Next.js in your React projects"," to further your understanding of the topic.",[682,734,736],{"id":735},"why-should-you-use-sanity","Why should you use Sanity?",[687,738,739],{},"Sanity CMS lets you treat content like data by creating a content lake. In a content lake, all your content is structured together and readily available for collaborative authoring. It is a real-time database for content in the Sanity studio. The Sanity studio is an open-source single-page application that uses schemas to let users organize content within the system.",[741,742,744],"h3",{"id":743},"what-is-a-schema","What is a Schema?",[687,746,747],{},"Schemas are the structures in a database for organizing images, texts, tables, attributes, references, and other types of media. Schemas are a plus for building server-side rendering applications with Next.js or Gatsby by providing additional information about the content of pages to web crawlers.",[741,749,751],{"id":750},"types-of-schemas-in-sanity","Types of Schemas in Sanity",[687,753,754],{},"These are the most common schema types you will encounter when working with Sanity.io:",[756,757,758,762,765,768,771,774,777,780],"ul",{},[759,760,761],"li",{},"Object: Defines reusable and nested fields for complex data relationships.",[759,763,764],{},"String: Represents plain text content.",[759,766,767],{},"Number: Stores numerical values.",[759,769,770],{},"Boolean: Represents true or false values.",[759,772,773],{},"Array: Creates lists or arrays of other schema types.",[759,775,776],{},"Reference: Establishes relationships between documents.",[759,778,779],{},"Image: Specifically designed for storing images.",[759,781,782],{},"Date: Stores date and time values.",[687,784,785],{},"Understanding these schema types empowers you to create structured and dynamic content in Sanity.io.",[682,787,789],{"id":788},"getting-started-with-sanity-headless-cms","Getting started with Sanity Headless CMS",[687,791,792,793,798],{},"First things first, we need to have Node.js installed. If you don’t have Node.js, ",[690,794,797],{"href":795,"rel":796},"https:\u002F\u002Fnodejs.org\u002Fen\u002Fdownload\u002F",[694],"download it here",". Once we have that downloaded and installed, let’s install the Sanity CLI using the command below:",[800,801,806],"pre",{"className":802,"code":804,"language":805},[803],"language-text","npm install -g @sanity\u002Fcli\n","text",[807,808,804],"code",{"__ignoreMap":809},"",[687,811,812],{},[690,813,816],{"href":814,"rel":815},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=230848aeac",[694],"Save this snippet",[687,818,819],{},"Once we have installed the Sanity CLI, we will initialize a new Sanity headless CMS project by running the command:",[800,821,824],{"className":822,"code":823,"language":805},[803],"sanity init\n",[807,825,823],{"__ignoreMap":809},[687,827,828],{},[690,829,816],{"href":830,"rel":831},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=59c2439a2e",[694],[687,833,834],{},"After running the command, we will create an account with Sanity using any of the signup methods below:",[687,836,837],{},[838,839],"img",{"alt":840,"src":841},"sanity.io project set up","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fimg-001.png",[687,843,844],{},"Once the authentication finishes, you’ll have to give a name to our project. I named it “sanity_tutorial”, but you can call yours whatever you want.",[687,846,847],{},[838,848],{"alt":849,"src":850},"screenshot of successful login confirmation","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fimg-002.png",[687,852,853],{},"Click on “Enter,” and you'll specify if you want your project to be public or private. Choose \"public\" by inputting \"Y\" and clicking “Enter.”",[687,855,856],{},[838,857],{"alt":858,"src":859},"screenshot showing project privacy settings","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fimg-003.png",[687,861,862],{},"Declare an existing path to set up the project on your PC.",[687,864,865],{},[838,866],{"alt":809,"src":867},"https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fimg-004.png",[687,869,870],{},"Click “Enter” and select a schema or template. You’ll be choosing a clean template with no predefined schemas. After clicking “Enter,” you’ll have a project with files and node dependencies in your folder.",[687,872,873],{},[838,874],{"alt":875,"src":876},"screenshot showing the files and node dependencies ","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fimg-005.png",[687,878,879],{},"Now that you've created your project, you can start using some helpful scripts provided by Sanity. By default, there are two scripts in the project's “package.json” file:",[881,882,883,889],"ol",{},[759,884,885,888],{},[698,886,887],{},"sanity start"," - This will run our studio locally at localhost:3333.",[759,890,891,894],{},[698,892,893],{},"sanity build"," - This will generate our current Sanity configuration to a static build.",[682,896,898],{"id":897},"getting-into-the-sanity-studio","Getting into the Sanity Studio",[687,900,901],{},"The studio UI is pretty cool. We’ll have a look at how it looks locally on our browser. But first, we’ll have to run the command:",[800,903,906],{"className":904,"code":905,"language":805},[803],"sanity start\n",[807,907,905],{"__ignoreMap":809},[687,909,910],{},[690,911,816],{"href":912,"rel":913},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=3a2946bcc8",[694],[687,915,916],{},"Next, we’ll visit localhost:3333. After that, sanity will connect, and we’ll sign in with our earlier method when setting up our project.",[687,918,919],{},[838,920],{"alt":921,"src":922},"screenshot showing sanity sign in","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fimg-006.png",[687,924,925],{},"Once we have signed into the studio, we’ll notice that it has no content or schemas. The studio is empty because we had selected “Clean project with no predefined schemas” before creating the studio. So now, let’s add some schemas.",[741,927,929],{"id":928},"creating-schemas","Creating Schemas",[687,931,932],{},"Back in our code editor, we will find a file called “schema.js” under the schema folder of our project. This file is where all the schemas we create will be imported and used. Let’s read the comments provided in the file to have a bit more understanding of what’s going on before we proceed:",[800,934,937],{"className":935,"code":936,"language":805},[803],"\u002F\u002F First, we must import the schema creator\nimport createSchema from 'part:@sanity\u002Fbase\u002Fschema-creator'\n\u002F\u002F Then import schema types from any plugins that might expose them\nimport schemaTypes from 'all:part:@sanity\u002Fbase\u002Fschema-type'\n\u002F\u002F Then we give our schema to the builder and provide the result to Sanity\nexport default createSchema({\n    \u002F\u002F We name our schema\n    name: 'default',\n    \u002F\u002F Then proceed to concatenate our document type\n    \u002F\u002F to the ones provided by any plugins that are installed\n    types: schemaTypes.concat([\n    \u002F* Your types here! *\u002F\n  ]),\n})\n",[807,938,936],{"__ignoreMap":809},[687,940,941],{},[690,942,816],{"href":943,"rel":944},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=c0e74388a8",[694],[687,946,947,948,951],{},"Create a file in the schemas folder and call it ",[807,949,950],{},"firstSchema.js",". In the file, we have to declare a type for the schema. Depending on the schema type we use, specific properties are required to go along it. We will use the document type for this current schema, which requires a name, title, and input field. The key for input fields in Sanity, called “fields”, is a property that lets us declare the kind of input to expect. We’ll be using the string type input field.",[800,953,956],{"className":954,"code":955,"language":805},[803],"export default {\n  type: \"document\", \u002F\u002Fvalue must be a schema type e.g document\n  name: \"author\", \u002F\u002Fvalue can be any word\n  title: \"Author\", \u002F\u002Fvalue can be any word\n  fields: [\n    {\n      type: \"string\",\n      name: \"name\",\n      title: \"Author's Name\"\n    }\n  ]\n}\n",[807,957,955],{"__ignoreMap":809},[687,959,960],{},[690,961,816],{"href":962,"rel":963},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=d58644b802",[694],[687,965,966,967,970,971,974,975,978,979,981],{},"Let’s go back to ",[807,968,969],{},"schema.js"," and delete the comments to have a clearer view of what we’re about to do. Then, just above the ",[698,972,973],{},"createSchema"," component, import the schema we’ve just created, ",[698,976,977],{},"firstSchema,"," as a type into the ",[698,980,973],{}," component like so:",[800,983,986],{"className":984,"code":985,"language":805},[803],"import firstSchema from \".\u002FfirstSchema\"\nexport default createSchema({\n    name: 'default',\n    types: schemaTypes.concat([\n    firstSchema,\n  ]),\n})\n",[807,987,985],{"__ignoreMap":809},[687,989,990],{},[690,991,816],{"href":992,"rel":993},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=236b4fbb28",[694],[687,995,996,997,1000,1001,1003],{},"Save the changes and visit localhost:3333. Next, we’ll see the title of the schema we created, ",[698,998,999],{},"Author",", displayed. ",[698,1002,999],{}," contains all the schema properties we defined in our project. With these properties, we’ll be able to input and publish new content from the studio to the application.",[687,1005,1006],{},[838,1007],{"alt":1008,"src":1009},"screenshot showing localhost:3333, the schema title and author","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fimg-007.png",[687,1011,1012,1013,1015],{},"Click on Publish, and the ",[698,1014,999],{}," will be saved to the studio.",[741,1017,1019],{"id":1018},"referencing-schemas","Referencing Schemas",[687,1021,1022,1023,1026,1027,1030,1031,1034,1035,1038,1039,1041,1042,1044],{},"Reference is a schema type for modeling relations between documents. It models one or more relations and stores the reference in an array. Let’s create a second file under the schemas folder called ",[807,1024,1025],{},"secondSchema.js",". This schema will refer to the first schema we created, but its properties will be quite different. The schema will be of the type document with the name “",[698,1028,1029],{},"book","” and title “",[698,1032,1033],{},"Book","” but with input fields of the types “string,” “image,” and “reference.” The “reference” type requires an additional property called “",[698,1036,1037],{},"to",",” which will contain the single or multiple schemas we want to refer to in “",[698,1040,1029],{},".” In this case, we want the “",[698,1043,1029],{},"” to refer to its author from the first schema.",[800,1046,1049],{"className":1047,"code":1048,"language":805},[803],"export default {\n  type: \"document\",\n  name: \"book\",\n  title: \"Book\",\n  fields: [\n    {\n      type: \"string\",\n      name: \"name\",\n      title: \"Book Name\"\n    },\n    {\n      type: \"image\",\n      name: \"image\",\n      title: \"Book Image\"\n    },\n    {\n      type: \"reference\",\n      name: \"author\",\n      title: \"Author\",\n      to: { type: \"author\"}\n    }\n  ]\n}\n",[807,1050,1048],{"__ignoreMap":809},[687,1052,1053],{},[690,1054,816],{"href":1055,"rel":1056},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=9e174ebace",[694],[687,1058,1059],{},"We will also need to provide a slug as an ID to navigate between different pages in our Next.js application later. Let’s add that right under the string type like so:",[800,1061,1064],{"className":1062,"code":1063,"language":805},[803],"fields: [\n{\ntype: \"string\",\nname: \"name\",\ntitle: \"Book Name\"\n},\n{\ntype: \"slug\",\nname: \"slug\",\ntitle: \"Slug\"\n},\n{\ntype: \"image\",\nname: \"image\",\ntitle: \"Book Image\"\n},\n{\ntype: \"reference\",\nname: \"author\",\ntitle: \"Author\",\nto: { type: \"author\"}\n}\n]\n",[807,1065,1063],{"__ignoreMap":809},[687,1067,1068],{},[690,1069,816],{"href":1070,"rel":1071},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=bc1f4fa5a9",[694],[687,1073,1074,1075,1078,1079,1081,1082,1084],{},"To see this schema and its reference in the studio, import ",[807,1076,1077],{},"secondSchema"," into ",[807,1080,969],{}," and insert it in the ",[807,1083,973],{}," component.",[800,1086,1089],{"className":1087,"code":1088,"language":805},[803],"import firstSchema from \".\u002FfirstSchema\"\nimport secondSchema from \".\u002FsecondSchema\";\nexport default createSchema({\nname: 'default',\ntypes: schemaTypes.concat([\nfirstSchema,\nsecondSchema\n]),\n})\n",[807,1090,1088],{"__ignoreMap":809},[687,1092,1093],{},[690,1094,816],{"href":1095,"rel":1096},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=06d84c90b9",[694],[687,1098,1099,1100,1103],{},"Save the changes and visit localhost:3333. Then, click “",[698,1101,1102],{},"Book,","” and we’ll see the second schema’s properties. Let’s give the book a name. For the slug, use an ID of 1 because this is our first book. Add an image for the book, and for the last input field, which has the reference type, select an author from the dropdown.",[687,1105,1106],{},[838,1107],{"alt":1108,"src":1109},"screenshot showing locahost:3333 content, book, and publish","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fimg-008.png",[687,1111,1112],{},"Great! Let’s see how we can use this content across multiple front-end applications like Next.js.",[682,1114,1116],{"id":1115},"connecting-sanityio-to-nextjs","Connecting Sanity.io to Next.js",[687,1118,1119],{},"Let’s set up our Next.js Sanity project by running the command:",[800,1121,1124],{"className":1122,"code":1123,"language":805},[803],"npx create-next-app\n",[807,1125,1123],{"__ignoreMap":809},[687,1127,1128],{},[690,1129,816],{"href":1130,"rel":1131},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=32cb43ab64",[694],[687,1133,1134,1135,1138,1139,1142,1143,1146],{},"In the ",[807,1136,1137],{},"index.js"," file of the pages folder, delete all the content in the “",[698,1140,1141],{},"Home()","” functional component and replace it with what we want the header of our homepage to be. First, we’ll create a ",[698,1144,1145],{},"div"," tag containing just the header:",[800,1148,1151],{"className":1149,"code":1150,"language":805},[803],"export default function Home() {\nreturn (\nBooks\n)\n}\n",[807,1152,1150],{"__ignoreMap":809},[687,1154,1155],{},[690,1156,816],{"href":1157,"rel":1158},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=8d4f49b27b",[694],[687,1160,1161,1162,1165,1166,1169,1170,1172,1173,1176],{},"Let’s have the name of our book right below the ",[698,1163,1164],{},"h1"," tag. But how do we get the book we created in the Sanity studio into this component? We’ll use a special server-side rendering function from Next.js called ",[698,1167,1168],{},"getServerSideProps"," and a query language from Sanity.io called “GROQ.” Right below the ",[807,1171,1141],{}," component, we will export an asynchronous ",[807,1174,1175],{},"getServerSideProps()"," function. Inside this function will be a GROQ query describing the type or nature of the information we want to fetch, a URL, a response, and a return statement. Since we want to fetch the book’s content from the studio, this is what the query will look like:",[800,1178,1181],{"className":1179,"code":1180,"language":805},[803],"const query = `*[ _type == \"book\" ]`\n",[807,1182,1180],{"__ignoreMap":809},[687,1184,1185],{},[690,1186,816],{"href":1187,"rel":1188},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=e39845a191",[694],[687,1190,1191],{},"And if we were to fetch the author’s content, the query would look like this:",[800,1193,1196],{"className":1194,"code":1195,"language":805},[803],"const query = `*[ _type == \"author\" ]`\n",[807,1197,1195],{"__ignoreMap":809},[687,1199,1200],{},[690,1201,816],{"href":1202,"rel":1203},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=78134aac64",[694],[687,1205,1206,1207,1210],{},"Now that we have our query, we will have to encode it with ",[807,1208,1209],{},"encodeURIComponent()",".",[800,1212,1215],{"className":1213,"code":1214,"language":805},[803],"const query = encodeURIComponent(`*[ _type == \"book\" ]`)\n",[807,1216,1214],{"__ignoreMap":809},[687,1218,1219],{},[690,1220,816],{"href":1221,"rel":1222},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=887344824c",[694],[687,1224,1225,1226,1231],{},"For the next step, let’s get the project ID from ",[690,1227,1230],{"href":1228,"rel":1229},"https:\u002F\u002Fwww.sanity.io\u002Flogin",[694],"https:\u002F\u002Fwww.sanity.io",". First, sign in using the previous method. Once signed in, click on the Sanity project we are working with, and you will find your project ID. Copy the project ID and paste it into an environment variable. Next, we will have to set a URL for the fetch request we are about to make with the query. The URL will contain our project ID and our query.",[800,1233,1236],{"className":1234,"code":1235,"language":805},[803],"const url = `https:\u002F\u002FYOUR_PROJECT_ID.api.sanity.io\u002Fv1\u002Fdata\u002Fquery\u002Fproduction?query=${query}`\n",[807,1237,1235],{"__ignoreMap":809},[687,1239,1240],{},[690,1241,816],{"href":1242,"rel":1243},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=42de4a99e3",[694],[687,1245,1246,1247,1210],{},"Now, we need to fetch a response from the URL and convert that to JSON. The response is going to return three objects named “ms,” “query,” and “result.” We are only interested in the result since that is where all of our content is stored, so we will get that result and return it as props in ",[807,1248,1175],{},[800,1250,1253],{"className":1251,"code":1252,"language":805},[803],"const response = await fetch(url).then(res => res.json())\nreturn {\nprops: {\nbook: response.result\n}\n",[807,1254,1252],{"__ignoreMap":809},[687,1256,1257],{},[690,1258,816],{"href":1259,"rel":1260},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=c50f4f8915",[694],[687,1262,1263],{},"In the end, we will get a function in Next.js that fetches content from Sanity:",[800,1265,1268],{"className":1266,"code":1267,"language":805},[803],"export async function getServerSideProps(){\n  const query = encodeURIComponent(`*[ _type == \"book\" ]`)\n  const url = `https:\u002F\u002FYOUR_PROJECT_ID.api.sanity.io\u002Fv1\u002Fdata\u002Fquery\u002Fproduction?query=${query}`\n  const response = await fetch(url).then(res => res.json())\n  return {\n    props: {\n      book: response.result\n    }\n  }\n}\n",[807,1269,1267],{"__ignoreMap":809},[687,1271,1272],{},[690,1273,816],{"href":1274,"rel":1275},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=b03a4e9855",[694],[687,1277,1278,1279,1281,1282,1284],{},"Now that we have our content in our application, we have to display it. So in the ",[807,1280,1141],{}," functional component, let’s parse in the props from ",[807,1283,1175],{}," and use the props underneath our header. The result from Sanity is an array, and we do have just one book created in the studio, but we will be using a mapping just in case we want to add more content to the studio in the future.",[800,1286,1289],{"className":1287,"code":1288,"language":805},[803],"export default function Home({ book }) {\n  return (\n    Books          {book.map((b) => {         return (                      {b.name}                 )      })}      \n )\n}\n",[807,1290,1288],{"__ignoreMap":809},[687,1292,1293],{},[690,1294,816],{"href":1295,"rel":1296},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=7d934bb4ee",[694],[687,1298,1299],{},"Let’s save this and run the app in development mode by running the command:",[800,1301,1304],{"className":1302,"code":1303,"language":805},[803],"npm run dev\n",[807,1305,1303],{"__ignoreMap":809},[687,1307,1308],{},[690,1309,816],{"href":1310,"rel":1311},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=f862419f14",[694],[687,1313,1314],{},"And visiting localhost:3000:",[687,1316,1317],{},[838,1318],{"alt":1319,"src":1320},"sanity tutorial book being displayed on a localhost:3000 webpage","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fimg-009.png",[687,1322,1323],{},"We’ll see our book displayed! Now let’s get the rest of our content on a different page. This way, if we create more content in the studio, we will be able to see a list of multiple books on our homepage and their details on different pages.",[741,1325,1327],{"id":1326},"displaying-more-sanity-headless-cms-content","Displaying More Sanity Headless CMS Content",[687,1329,1330,1331,1335,1336,1338,1339,1341],{},"Next.js is amazing when it comes to moving between pages. The process is called “Dynamic Routing”. Remember, we used a slug for our second schema (Book) at the Sanity studio to serve as a custom unique identifier. We will input that slug at the end of our URL to navigate between the pages in Next.js. Let’s create a subfolder in pages called “bookInfo”. The “bookInfo” folder will have a file for our slugs called “",[1332,1333,1334],"span",{},"slug",".js”. The brackets tell Next.js to treat the file as a dynamic route. Inside “",[1332,1337,1334],{},".js”, export an asynchronous ",[807,1340,1175],{}," which will expect a context as an argument.",[800,1343,1346],{"className":1344,"code":1345,"language":805},[803],"export const getServerSideProps = async context => {}\n",[807,1347,1345],{"__ignoreMap":809},[687,1349,1350],{},[690,1351,816],{"href":1352,"rel":1353},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=7f874c9f53",[694],[687,1355,1356,1357,1359,1360,1363],{},"In ",[807,1358,1175],{},", we will query the slug from the context and store it in a variable called ",[807,1361,1362],{},"pageSlug"," like so:",[800,1365,1368],{"className":1366,"code":1367,"language":805},[803],"const pageSlug = context.query.slug\n",[807,1369,1367],{"__ignoreMap":809},[687,1371,1372],{},[690,1373,816],{"href":1374,"rel":1375},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=992243bbc5",[694],[687,1377,1378,1379,1381],{},"Let’s create our query with GROQ, but this time we will use the page’s slug and ensure the slug corresponds with the properties of “",[698,1380,1029],{},".”",[800,1383,1386],{"className":1384,"code":1385,"language":805},[803],"const query = encodeURIComponent(`*[ slug.current == \"${pageSlug}\" && _type == \"book\" ]`)\n",[807,1387,1385],{"__ignoreMap":809},[687,1389,1390],{},[690,1391,816],{"href":1392,"rel":1393},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=a5cb48b4ee",[694],[687,1395,1396],{},"Now, we’ll create a URL like we did before and fetch a response.",[800,1398,1401],{"className":1399,"code":1400,"language":805},[803],"const response = await fetch(url).then(res => res.json())\n",[807,1402,1400],{"__ignoreMap":809},[687,1404,1405],{},[690,1406,816],{"href":1407,"rel":1408},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=9d6540835c",[694],[687,1410,1411],{},"The response has a result object which contains our book’s name, the book’s image, and the book’s author. We expect the book to have only one detail, so we do not need to map through the result. Let’s store the book’s name into a variable called “book” like so:",[800,1413,1416],{"className":1414,"code":1415,"language":805},[803],"const book = response.result[0].name\n",[807,1417,1415],{"__ignoreMap":809},[687,1419,1420],{},[690,1421,816],{"href":1422,"rel":1423},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=8e764fa22b",[694],[687,1425,1426],{},"To get our image, we must download a package from Sanity, which will provide a source URL. Run the command:",[800,1428,1431],{"className":1429,"code":1430,"language":805},[803],"npm install @sanity\u002Fimage-url\n",[807,1432,1430],{"__ignoreMap":809},[687,1434,1435],{},[690,1436,816],{"href":1437,"rel":1438},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=b59b459975",[694],[687,1440,1441,1442,1445],{},"And import the ",[807,1443,1444],{},"imageUrlBuilder()"," from the package like so:",[800,1447,1450],{"className":1448,"code":1449,"language":805},[803],"import imageUrlBuilder from \"@sanity\u002Fimage-url\"\n",[807,1451,1449],{"__ignoreMap":809},[687,1453,1454],{},[690,1455,816],{"href":1456,"rel":1457},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=3eae47af6e",[694],[687,1459,1460,1461,1463,1464,1466],{},"Inside ",[807,1462,1175],{},", We have to provide our project ID and dataset as an object to ",[807,1465,1444],{}," and store it into a variable like so:",[800,1468,1471],{"className":1469,"code":1470,"language":805},[803],"const builder = imageUrlBuilder({\n  projectId: \"YOUR_PROJECT_ID\",\n  dataset: \"production\"\n})\n",[807,1472,1470],{"__ignoreMap":809},[687,1474,1475],{},[690,1476,816],{"href":1477,"rel":1478},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=261d47899d",[694],[687,1480,1481],{},"With that variable, let’s call the image builder and parse the original return value for our book’s image.",[800,1483,1486],{"className":1484,"code":1485,"language":805},[803],"const bookImage = builder.image(response.result[0].image).url()\n",[807,1487,1485],{"__ignoreMap":809},[687,1489,1490],{},[690,1491,816],{"href":1492,"rel":1493},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=db71438fd0",[694],[687,1495,1496,1497,1500,1501,1503,1504,1507],{},"Lastly, we’ll need to get our book’s author. The author in the second schema is not of type string. Instead, the author is of the type reference, so we will make a GROQ query using the reference content in the second schema’s author to get the string content of the first schema’s author. The content of the reference type is also the same as the “_id” type of our first schema. ",[807,1498,1499],{},"_id"," is an extended text format generated by Sanity for organizing content. Let’s make a query for our author using an asynchronous function outside of ",[807,1502,1175],{},". We’ll call this function “",[807,1505,1506],{},"getAuthor","”, and it will contain the following:",[800,1509,1512],{"className":1510,"code":1511,"language":805},[803],"async function getAuthor(id){\n  const query = encodeURIComponent(`*[ _id == \"${id}\" ]`)\n  const url = `https:\u002F\u002FYOUR_PROJECT_ID.api.sanity.io\u002Fv1\u002Fdata\u002Fquery\u002Fproduction?query=${query}`\n  const response = await fetch(url).then(res => res.json())\n    return(response.result[0].name)\n}\n",[807,1513,1511],{"__ignoreMap":809},[687,1515,1516],{},[690,1517,816],{"href":1518,"rel":1519},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=2d1047823c",[694],[687,1521,1522,1523,1525],{},"So we are saying we want to make a query for the “_id“ type in our studio and return the name of the author. Back in ",[807,1524,1175],{},", let’s use the function we just created to get our author. The author contains two objects: the “_type” and “_ref”. We will parse in “_ref” as the id for the function like so:",[800,1527,1530],{"className":1528,"code":1529,"language":805},[803],"const author = await getAuthor(response.result[0].author._ref)\n",[807,1531,1529],{"__ignoreMap":809},[687,1533,1534],{},[690,1535,816],{"href":1536,"rel":1537},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=47c54c91d0",[694],[687,1539,1540],{},"Sweet! We’ve got all of our content. Once we return them as props, we’ll get something like this:",[800,1542,1545],{"className":1543,"code":1544,"language":805},[803],"export const getServerSideProps = async details => {\n  const pageSlug = details.query.slug\n  const query = encodeURIComponent(`*[ slug.current == \"${pageSlug}\" && _type == \"book\" ]`)\n  const url = `https:\u002F\u002FYOUR_PROJECT_ID.api.sanity.io\u002Fv1\u002Fdata\u002Fquery\u002Fproduction?qery=${query}`\n  const response = await fetch(url).then(res => res.json())\n  const book = response.result[0].name\n  const builder = imageUrlBuilder({\n    projectId: \"YOUR_PROJECT_ID\",\n    dataset: \"production\"\n})\nconst bookImage = builder.image(response.result[0].image).url()\nconst author = await getAuthor(response.result[0].author._ref)\nreturn {\n  props: {\n    book: book,\n    bookImage: bookImage,\n    author: author\n  }\n }\n}\n",[807,1546,1544],{"__ignoreMap":809},[687,1548,1549],{},[690,1550,816],{"href":1551,"rel":1552},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=2bd2469d64",[694],[687,1554,1555],{},"All we have to do now is parse the three props into our default functional component like so:",[800,1557,1560],{"className":1558,"code":1559,"language":805},[803],"export default function BookInfo({ book, bookImage, author })\n  {return(\n              {book} is a book published by {author}     \n  )\n}\n",[807,1561,1559],{"__ignoreMap":809},[687,1563,1564],{},[690,1565,816],{"href":1566,"rel":1567},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=15124280e5",[694],[687,1569,1570,1571,1573,1574,1577,1578,1580],{},"Let’s return to our “index.js” file and connect it to the “",[1332,1572,1334],{},".js” with ",[807,1575,1576],{},"useRouter()",", a function in Next.js that lets us move smoothly between clicked pages in the application. For example, when we click on a book on our homepage, Next.js will change our route to a page containing the book’s details. So, in index.js, import the ",[807,1579,1576],{},":",[800,1582,1585],{"className":1583,"code":1584,"language":805},[803],"import { useRouter } from \"next\u002Frouter\"\n",[807,1586,1584],{"__ignoreMap":809},[687,1588,1589],{},[690,1590,816],{"href":1591,"rel":1592},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=ae644f8a0b",[694],[687,1594,1595,1596,1599],{},"And store it in a const variable called ",[807,1597,1598],{},"router",". Make sure the variable is inside the default functional component:",[800,1601,1604],{"className":1602,"code":1603,"language":805},[803],"const router = useRouter()\n",[807,1605,1603],{"__ignoreMap":809},[687,1607,1608],{},[690,1609,816],{"href":1610,"rel":1611},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=abab43ac3a",[694],[687,1613,1614,1615,1618,1619,1621],{},"We’ll use the router and its push method in an ",[807,1616,1617],{},"onClick()"," event for the ",[807,1620,759],{}," tag, which contains the name of our books. Inside the push method, we’ll provide the slug of the page we want to navigate to like so:",[800,1623,1626],{"className":1624,"code":1625,"language":805},[803],"{book.map((b) => {\n  return (\n router.push(`\u002FbookInfo\u002F${b.slug.current}`)} key={b}>\n      {b.name}\n  )\n})}\n",[807,1627,1625],{"__ignoreMap":809},[687,1629,1630],{},[690,1631,816],{"href":1632,"rel":1633},"https:\u002F\u002Fmariah.pieces.cloud\u002F?p=60ee4c8ad6",[694],[687,1635,1636],{},"Save, go to localhost:3000, and click on the book “Sanity Tutorial”:",[687,1638,1639],{},[838,1640],{"alt":1641,"src":1642},"screenshot showing locahost:3333 with a header image that shows suspended tv screens in a large room, and the book title and author name","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fimg-010.png",[687,1644,1645],{},"And there’s all of our content :). Sanity.io lets us take the wheel when styling content for our front-end. We can add more books and authors to the studio, and they'll be rendered to the front-end automatically.",[682,1647,1649],{"id":1648},"conclusion","Conclusion",[687,1651,1652,1653,1210],{},"Sanity.io is a flexible management system that lets users structure content however they see fit. Sanity.io CMS is great for working with static and server-side rendered sites. Users can create blogs, portfolios, eCommerce websites, and many more applications with the Sanity headless CMS. It takes a little time to get started in the studio, but even less time when adding new content to an existing schema. In this tutorial, we covered a few of the features Sanity has to offer, but there are many more features you can explore on our blog to create fast and responsive websites, such as this one on creating a ",[690,1654,1657],{"href":1655,"rel":1656},"https:\u002F\u002Fpieces.app\u002Fblog\u002Fbuilding-a-headless-wordpress-site-with-vuejs",[694],"headless WordPress site",{"title":809,"searchDepth":1659,"depth":1659,"links":1660},2,[1661,1662,1667,1668,1672,1675],{"id":684,"depth":1659,"text":685},{"id":735,"depth":1659,"text":736,"children":1663},[1664,1666],{"id":743,"depth":1665,"text":744},3,{"id":750,"depth":1665,"text":751},{"id":788,"depth":1659,"text":789},{"id":897,"depth":1659,"text":898,"children":1669},[1670,1671],{"id":928,"depth":1665,"text":929},{"id":1018,"depth":1665,"text":1019},{"id":1115,"depth":1659,"text":1116,"children":1673},[1674],{"id":1326,"depth":1665,"text":1327},{"id":1648,"depth":1659,"text":1649},"Software Development","2022-12-02T00:00:00.000Z","Learn how you can create text, images, and other media types with Sanity Headless CMS and display that content in your Next.js application.",false,"md","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs\u002Fhero.jpeg","decorative cover image showing two doors",{},"\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs",{"title":673,"description":1678},"blog\u002Fhow-to-create-sanity-headless-cms-in-nextjs","K60FzFV-E804OMAbChROCNtG6BOd0_e2DS5OtGIimvc",{"id":1689,"title":674,"body":1690,"description":809,"draft":1679,"extension":1680,"meta":1694,"navigation":32,"path":1695,"photo":1696,"photoAlt":676,"seo":1697,"stem":1698,"__hash__":1699},"authors\u002Fauthors\u002Fsage-osoro.md",{"type":679,"value":1691,"toc":1692},[],{"title":809,"searchDepth":1659,"depth":1659,"links":1693},[],{},"\u002Fauthors\u002Fsage-osoro","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fauthors\u002Fsage-osoro.jpg",{"title":674,"description":809},"authors\u002Fsage-osoro","eOzmqrF3uDwizDgwrjudaWbfCSJJ98Ie5kQcz6Uh-Bw",{"left":1701,"top":1701,"width":1702,"height":1702,"rotate":1701,"vFlip":1679,"hFlip":1679,"body":1703},0,24,"\u003Cpath fill=\"currentColor\" d=\"m7.825 13l4.9 4.9q.3.3.288.7t-.313.7q-.3.275-.7.288t-.7-.288l-6.6-6.6q-.15-.15-.213-.325T4.426 12t.063-.375t.212-.325l6.6-6.6q.275-.275.688-.275t.712.275q.3.3.3.713t-.3.712L7.825 11H19q.425 0 .713.288T20 12t-.288.713T19 13z\"\u002F>"]