[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation":3,"url-settings":86,"blog-\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs":663,"blog-author-\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs":1671,"i-material-symbols:arrow-back-rounded":1683},{"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},"Sign in","url:portal.home",{"label":79,"href":62},"Get in touch",{"label":81,"href":82},"Download","url:routes.downloads",{},"data\u002Fshared\u002Fnavigation","VdirGIa8cUm6xLprbBeTKcw914JfyJjWfF-9hSVOX5Y",{"id":87,"extension":5,"links":88,"meta":660,"stem":661,"__hash__":662},"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,295,299,303,306,310,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,453,457,461,465,469,473,477,480,483,486,489,493,497,500,504,508,512,516,520,524,528,532,536,540,544,548,551,555,559,563,567,571,574,577,580,584,587,591,595,599,603,606,610,614,617,620,623,627,631,635,638,641,644,648,652,656],{"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.piecesOS","PiecesOS manual installation","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies\u002Fpieces-os\u002Fmanual-installation",{"key":209,"label":210,"href":211},"extensions.chrome","Chrome extension","https:\u002F\u002Fchrome.google.com\u002Fwebstore\u002Fdetail\u002Fpieces-save-code-snippets\u002Figbgibhbfonhmjlechmeefimncpekepm",{"key":213,"label":214,"href":215},"extensions.firefox","Firefox add-on","https:\u002F\u002Faddons.mozilla.org\u002Fen-US\u002Ffirefox\u002Faddon\u002Fpieces-save-code-from-the-web\u002F",{"key":217,"label":218,"href":219},"extensions.edge","Edge add-on","https:\u002F\u002Fmicrosoftedge.microsoft.com\u002Faddons\u002Fdetail\u002Fpieces-save-code-snippet\u002Fhglfimcdgonaeeobjckfdabcldfidmim",{"key":221,"label":222,"href":223},"extensions.vscode","VS Code extension","https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=MeshIntelligentTechnologiesInc.pieces-vscode",{"key":225,"label":226,"href":227},"extensions.visualStudio","Visual Studio extension","https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=MeshIntelligentTechnologiesInc.PiecesVisualStudio",{"key":229,"label":230,"href":231},"extensions.jetbrains","JetBrains plugin","https:\u002F\u002Fplugins.jetbrains.com\u002Fplugin\u002F17328-pieces--save-search-share--reuse-code-snippets",{"key":233,"label":234,"href":235},"extensions.obsidian","Obsidian plugin","https:\u002F\u002Fobsidian.md\u002Fplugins?id=pieces-for-developers",{"key":237,"label":238,"href":239},"extensions.sublime","Sublime package","https:\u002F\u002Fpackagecontrol.io\u002Fpackages\u002FPieces",{"key":241,"label":242,"href":243},"extensions.neovim","Neovim plugin","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fplugin_neo_vim",{"key":245,"label":246,"href":247},"extensions.jupyterlab","JupyterLab plugin","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fjupyterlab-pieces",{"key":249,"label":250,"href":251},"extensions.cli","Pieces CLI","https:\u002F\u002Fpypi.org\u002Fproject\u002Fpieces-cli\u002F",{"key":253,"label":254,"href":255},"docs.home","Documentation home","https:\u002F\u002Fdocs.pieces.app",{"key":257,"label":258,"href":259},"docs.getStarted","Get started docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces",{"key":261,"label":262,"href":263},"docs.api","API docs","https:\u002F\u002Fdocs.pieces.app\u002Fapi",{"key":265,"label":266,"href":267},"docs.desktop.overview","Desktop overview","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop",{"key":269,"label":270,"href":271},"docs.desktop.onboarding","Desktop onboarding","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fonboarding",{"key":273,"label":274,"href":275},"docs.desktop.timeline","Desktop timeline docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Ftimeline",{"key":277,"label":278,"href":279},"docs.desktop.summaries","Desktop summaries docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fsingle-click-summaries",{"key":281,"label":282,"href":283},"docs.desktop.search","Desktop conversational search docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fconversational-search",{"key":285,"label":286,"href":287},"docs.desktop.drive","Desktop drive docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fdrive",{"key":289,"label":290,"href":291},"docs.desktop.account","Desktop account settings docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fdesktop\u002Fconfiguration\u002Faccount",{"key":293,"label":294,"href":92},"docs.desktop.download","Desktop download docs",{"key":296,"label":297,"href":298},"docs.piecesOS.overview","PiecesOS overview docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies",{"key":300,"label":301,"href":302},"docs.piecesOS.details","PiecesOS details docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies\u002Fpieces-os",{"key":304,"label":305,"href":207},"docs.piecesOS.install","PiecesOS install docs",{"key":307,"label":308,"href":309},"docs.piecesOS.quickMenu","PiecesOS quick menu docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies\u002Fpieces-os\u002Fquick-menu",{"key":311,"label":312,"href":313},"docs.piecesOS.storage","On-device storage docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies\u002Fon-device-storage",{"key":315,"label":316,"href":317},"docs.piecesOS.troubleshooting","PiecesOS troubleshooting docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fcore-dependencies\u002Fpieces-os\u002Ftroubleshooting",{"key":319,"label":320,"href":321},"docs.mcp.overview","MCP overview docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp",{"key":323,"label":324,"href":325},"docs.mcp.cursor","MCP Cursor docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fcursor",{"key":327,"label":328,"href":329},"docs.mcp.vscode","MCP VS Code docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fvs-code",{"key":331,"label":332,"href":333},"docs.mcp.claudeDesktop","MCP Claude Desktop docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fclaude-desktop",{"key":335,"label":336,"href":337},"docs.mcp.claudeCode","MCP Claude Code docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fclaude-code",{"key":339,"label":340,"href":341},"docs.mcp.claudeCowork","MCP Claude Cowork docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fclaude-cowork",{"key":343,"label":344,"href":345},"docs.mcp.githubCopilot","MCP GitHub Copilot docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fgithub-copilot",{"key":347,"label":348,"href":349},"docs.mcp.goose","MCP Goose docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fgoose",{"key":351,"label":352,"href":353},"docs.mcp.windsurf","MCP Windsurf docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fwindsurf",{"key":355,"label":356,"href":357},"docs.mcp.zed","MCP Zed docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fzed",{"key":359,"label":360,"href":361},"docs.mcp.jetbrains","MCP JetBrains docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fjetbrains-ides",{"key":363,"label":364,"href":365},"docs.mcp.continueDev","MCP Continue docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fcontinue-dev",{"key":367,"label":368,"href":369},"docs.mcp.cline","MCP Cline docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fcline",{"key":371,"label":372,"href":373},"docs.mcp.raycast","MCP Raycast docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fraycast",{"key":375,"label":376,"href":377},"docs.mcp.rovoDevCli","MCP Rovo Dev CLI docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Frovo-dev-cli",{"key":379,"label":380,"href":381},"docs.mcp.openaiCodexCli","MCP OpenAI Codex CLI docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fopenai-codex-cli",{"key":383,"label":384,"href":385},"docs.mcp.googleGeminiCli","MCP Google Gemini CLI docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fgoogle-gemini-cli",{"key":387,"label":388,"href":389},"docs.mcp.amazonQ","MCP Amazon Q docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Famazon-q-developer",{"key":391,"label":392,"href":393},"docs.mcp.chatgptDev","MCP ChatGPT Developer Mode docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fchatgpt-developer-mode",{"key":395,"label":396,"href":397},"docs.mcp.openclaw","MCP OpenClaw docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fopenclaw",{"key":399,"label":400,"href":401},"docs.mcp.mcpRemote","MCP Remote docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fmcp-remote",{"key":403,"label":404,"href":405},"docs.mcp.ngrok","MCP ngrok docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmcp\u002Fngrok-setup",{"key":407,"label":408,"href":409},"docs.troubleshooting.macOS","macOS troubleshooting docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Ftroubleshooting\u002Fmacos",{"key":411,"label":412,"href":413},"docs.troubleshooting.windows","Windows troubleshooting docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Ftroubleshooting\u002Fwindows",{"key":415,"label":416,"href":417},"docs.troubleshooting.linux","Linux troubleshooting docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fmeet-pieces\u002Ftroubleshooting\u002Flinux",{"key":419,"label":420,"href":421},"docs.privacy","Privacy and security docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fprivacy-security-your-data",{"key":423,"label":424,"href":425},"docs.support","Support docs","https:\u002F\u002Fdocs.pieces.app\u002Fproducts\u002Fsupport",{"key":427,"label":428,"href":429},"portal.home","Pieces portal","https:\u002F\u002Fportal.pieces.app",{"key":431,"label":432,"href":433},"site.home","Website home","https:\u002F\u002Fpieces.app",{"key":435,"label":436,"href":437},"site.about","About page","https:\u002F\u002Fpieces.app\u002Fabout",{"key":439,"label":440,"href":441},"site.features","Features page","https:\u002F\u002Fpieces.app\u002Ffeatures",{"key":443,"label":444,"href":445},"site.plugins","Plugins page","https:\u002F\u002Fpieces.app\u002Fplugins",{"key":447,"label":448,"href":449},"site.contact","Contact page","https:\u002F\u002Fpieces.app\u002Fcontact",{"key":451,"label":58,"href":452},"site.updates","https:\u002F\u002Fpieces.app\u002Fupdates",{"key":454,"label":455,"href":456},"site.news","News","https:\u002F\u002Fpieces.app\u002Fnews",{"key":458,"label":459,"href":460},"site.events","Community events","https:\u002F\u002Fpieces.app\u002Fcommunity\u002Fevents",{"key":462,"label":463,"href":464},"site.userStories","User stories","https:\u002F\u002Fpieces.app\u002Fuser-stories",{"key":466,"label":467,"href":468},"site.academy","Academy","https:\u002F\u002Fpieces.app\u002Flearn\u002Facademy",{"key":470,"label":471,"href":472},"site.support","Website support","https:\u002F\u002Fpieces.app\u002Fsupport",{"key":474,"label":475,"href":476},"site.standup","Standup","https:\u002F\u002Fpieces.app\u002Fstandup",{"key":478,"label":34,"href":479},"site.blog","https:\u002F\u002Fcode.pieces.app\u002Fblog",{"key":481,"label":43,"href":482},"social.discord","https:\u002F\u002Fdiscord.gg\u002Fgetpieces",{"key":484,"label":46,"href":485},"social.x","https:\u002F\u002Fx.com\u002Fgetpieces",{"key":487,"label":488,"href":485},"social.twitter","Twitter",{"key":490,"label":491,"href":492},"social.instagram","Instagram","https:\u002F\u002Fwww.instagram.com\u002Fgetpieces\u002F",{"key":494,"label":495,"href":496},"social.tiktok","TikTok","https:\u002F\u002Fwww.tiktok.com\u002F@getpieces",{"key":498,"label":49,"href":499},"social.linkedin","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fgetpieces\u002F",{"key":501,"label":502,"href":503},"social.youtube","YouTube","https:\u002F\u002Fyoutube.com\u002F@getpieces",{"key":505,"label":506,"href":507},"github.org","GitHub organization","https:\u002F\u002Fgithub.com\u002Fpieces-app",{"key":509,"label":510,"href":511},"github.support","GitHub support","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fsupport",{"key":513,"label":514,"href":515},"github.issues","GitHub issues","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fsupport\u002Fissues",{"key":517,"label":518,"href":519},"github.discussions","GitHub discussions","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fsupport\u002Fdiscussions",{"key":521,"label":522,"href":523},"github.documentation","GitHub documentation","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fdocumentation",{"key":525,"label":526,"href":527},"github.opensource","GitHub open source","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fopensource",{"key":529,"label":530,"href":531},"github.sdks.python","Python SDK","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fpieces-os-client-sdk-for-python",{"key":533,"label":534,"href":535},"github.sdks.typescript","TypeScript SDK","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fpieces-os-client-sdk-for-typescript",{"key":537,"label":538,"href":539},"github.sdks.dart","Dart SDK","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fpieces-os-client-sdk-for-dart",{"key":541,"label":542,"href":543},"github.sdks.kotlin","Kotlin SDK","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fpieces-os-client-sdk-for-kotlin",{"key":545,"label":546,"href":547},"github.plugins.obsidian","Obsidian plugin repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fobsidian-pieces",{"key":549,"label":550,"href":247},"github.plugins.jupyterlab","JupyterLab plugin repository",{"key":552,"label":553,"href":554},"github.plugins.sublime","Sublime plugin repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fplugin_sublime",{"key":556,"label":557,"href":558},"github.plugins.neovim","Neovim plugin repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fplugin_neovim",{"key":560,"label":561,"href":562},"github.cliAgent","CLI agent repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fcli-agent",{"key":564,"label":565,"href":566},"github.mcpDart","MCP Dart repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fmcp_dart",{"key":568,"label":569,"href":570},"github.awesomePieces","Awesome Pieces repository","https:\u002F\u002Fgithub.com\u002Fpieces-app\u002Fawesome-pieces",{"key":572,"label":573,"href":66},"legal.privacyPolicy","Privacy policy",{"key":575,"label":576,"href":69},"legal.refundPolicy","Refund policy",{"key":578,"label":579,"href":72},"legal.terms","Terms",{"key":581,"label":582,"href":583},"legal.security","Legal security","https:\u002F\u002Fpieces.app\u002Flegal\u002Fsecurity",{"key":585,"label":586,"href":503},"videos.youtubeChannel","YouTube channel",{"key":588,"label":589,"href":590},"videos.gettingStartedDesktop","Getting started desktop video","https:\u002F\u002Fyoutu.be\u002FdUr1lRM_TYk",{"key":592,"label":593,"href":594},"videos.snippetDiscoveryxR","Snippet discovery video","https:\u002F\u002Fyoutu.be\u002FG6vb1USw-30",{"key":596,"label":597,"href":598},"sales.bookACall","Book a sales call","https:\u002F\u002Fcalendar.app.google\u002FWVUDtUfNy5Vst3sH7",{"key":600,"label":601,"href":602},"sales.enterprise","Enterprise form","https:\u002F\u002Fgetpieces.typeform.com\u002Fto\u002FaVQFTvpE",{"key":604,"label":605,"href":519},"sales.feedback","Feedback discussions",{"key":607,"label":608,"href":609},"sales.earlyAccess","Early access form","https:\u002F\u002Fgetpieces.typeform.com\u002Fearlyaccess",{"key":611,"label":612,"href":613},"sales.supportEmail","Support email","mailto:support@pieces.app",{"key":615,"label":616,"href":19},"routes.home","Home route",{"key":618,"label":619,"href":56},"routes.about","About route",{"key":621,"label":622,"href":12},"routes.downloads","Downloads route",{"key":624,"label":625,"href":626},"routes.thanks","Post-install thanks route","\u002Finstall\u002Fthanks",{"key":628,"label":629,"href":630},"routes.pricing","Pricing route","\u002Fpricing",{"key":632,"label":633,"href":634},"cta.freeTrial","Start free trial CTA (Pieces Pro) — used by \u002Fcampaigns\u002F* landing pages","https:\u002F\u002Fcampaigns.pieces.app\u002F",{"key":636,"label":637,"href":22},"routes.enterprise","Enterprise route",{"key":639,"label":640,"href":62},"routes.contact","Contact route",{"key":642,"label":643,"href":59},"routes.updates","Updates route",{"key":645,"label":646,"href":647},"routes.migrationError","Migration error route","\u002Fmigration\u002Ferror",{"key":649,"label":650,"href":651},"routes.authenticated","Post-login authenticated route","\u002Fauth\u002Fsigned-in",{"key":653,"label":654,"href":655},"routes.signed-out","Signed out route","\u002Fauth\u002Fsigned-out",{"key":657,"label":658,"href":659},"routes.authentication-error","Authentication error route","\u002Fauth\u002Ferror",{},"data\u002Fshared\u002Furls","NLkVE1lIUws518K-1QsSB6T-GvlXYIzcRL1HDhqarGQ",{"id":664,"title":665,"author":666,"authorPhoto":667,"authorPhotoAlt":668,"authorSlug":669,"body":670,"buttonText":668,"buttonUrl":668,"category":1657,"date":1658,"description":1659,"draft":1660,"editorsPick":1660,"extension":1661,"featured":1660,"image":1662,"imageAlt":1663,"meta":1664,"navigation":32,"ogImage":668,"ogImageAlt":668,"path":1665,"seo":1666,"stem":1667,"tags":1668,"__hash__":1670},"blog\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs.md","Use Markdoc and Next.js to Build a Git-powered Markdown Blog","Miracle Onyenma","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fauthor.png",null,"miracle-onyenma",{"type":671,"value":672,"toc":1628},"minimark",[673,691,696,699,702,705,708,712,715,720,728,737,740,743,746,755,758,762,782,785,788,791,822,829,833,836,843,847,850,874,878,886,889,899,909,914,920,926,934,955,961,967,973,984,990,1012,1016,1019,1025,1028,1034,1040,1047,1050,1064,1070,1073,1077,1080,1086,1092,1095,1099,1105,1111,1117,1121,1126,1132,1144,1152,1159,1169,1172,1176,1179,1190,1206,1212,1218,1231,1245,1252,1258,1265,1271,1278,1284,1288,1291,1294,1298,1305,1309,1323,1345,1351,1357,1364,1368,1377,1383,1392,1403,1419,1426,1432,1442,1448,1452,1461,1467,1470,1476,1479,1486,1490,1505,1511,1514,1520,1528,1534,1537,1543,1549,1555,1561,1563,1567,1573,1588,1591,1597,1600,1606,1613,1619,1622],[674,675,676,677,684,685,690],"p",{},"Most modern developer blogs and documentation websites have one thing in common— they run on JAMstack (static websites) and their content is file-based and powered by Git. This allows multiple developers to collaboratively edit content with perks like versioning and version control. In this tutorial, we’re going to see how we can build a simple yet powerful and interactive blog with ",[678,679,683],"a",{"href":680,"rel":681},"https:\u002F\u002Fnextjs.org\u002F",[682],"nofollow","Next.js"," and ",[678,686,689],{"href":687,"rel":688},"https:\u002F\u002Fmarkdoc.dev\u002F",[682],"Markdoc",".",[692,693,695],"h2",{"id":694},"a-brief-overview-of-the-article","A Brief Overview of the Article",[674,697,698],{},"This tutorial will cover how we can leverage modern tools and frameworks to build a fast & performant blog without relying on a backend to manage our content.",[674,700,701],{},"We’ll look into Next.js, its features, and why it’s important. We'll then take a look at tools like Markdoc that we can use to author and render markdown content into pages for blogs and documentation sites.",[674,703,704],{},"We’ll also explore the pros and cons of this approach to building static blogs and documentation websites.",[674,706,707],{},"Let’s get right into it!",[692,709,711],{"id":710},"a-introduction-to-the-stack","A Introduction to the Stack",[674,713,714],{},"Let’s take a quick look at the tech stack we’ll be working with in this article.",[716,717,719],"h3",{"id":718},"jamstack","JAMstack",[674,721,722,727],{},[678,723,726],{"href":724,"rel":725},"https:\u002F\u002Fjamstack.org\u002F",[682],"JAMStack"," is an acronym for JavaScript API and Markup Stack. It's basically the way modern sites are built using tools like static site generators that can generate static content that is served over the internet. JavaScript is used for functionality and APIs are used to provide data.",[674,729,730,731,736],{},"For the past few years, since JAMstack became widespread, it has revolutionized the way many websites are built. ",[678,732,735],{"href":733,"rel":734},"https:\u002F\u002Fpieces.app\u002Fblog\u002Fbest-jamstack-frameworks-for-developing-static-and-dynamic-sites",[682],"JAMstack sites"," are fast and performant due to their static nature.",[674,738,739],{},"In order to provide content, APIs are used. These APIs can be called at build time during the static generation to provide content that will be sent to the client, but this is not the only way we can provide content.",[674,741,742],{},"We can use template files like Markdown to create content or even pages for our site using static site generators.",[716,744,683],{"id":745},"nextjs",[674,747,748,749,754],{},"According to ",[678,750,753],{"href":751,"rel":752},"https:\u002F\u002Fjamstack.org\u002Fgenerators\u002Fnext\u002F",[682],"Jamstack.org",", Next.js is a minimalistic framework for server-rendered React applications as well as statically exported React apps.",[674,756,757],{},"Since Next.js offers both Server Side Rendering (SSR) and Static Site Generation (SSG), it’s a great choice for building fast applications.",[716,759,761],{"id":760},"markdoc-filegit-based-content","Markdoc & File\u002FGit-based content",[674,763,748,764,769,770,775,776,781],{},[678,765,768],{"href":766,"rel":767},"https:\u002F\u002Fmarkdoc.dev\u002Fdocs\u002Fgetting-started",[682],"the official docs",", Markdoc is a Markdown-based document format and a framework for publishing content. It was designed at Stripe to meet the needs of their user-facing ",[678,771,774],{"href":772,"rel":773},"http:\u002F\u002Fstripe.com\u002Fdocs",[682],"product documentation",". Markdoc extends Markdown with a ",[678,777,780],{"href":778,"rel":779},"https:\u002F\u002Fmarkdoc.dev\u002Fdocs\u002Fsyntax",[682],"custom syntax"," for tags and annotations, providing a way to tailor content to individual users and introduce interactive elements.",[674,783,784],{},"With Markdoc, we can manage our content in markdown files and provide it to the frontend at build time without a database.",[674,786,787],{},"The Markdoc syntax is a superset of Markdown. This features markdown syntax with a few extensions to the syntax, such as tags and annotations.",[674,789,790],{},"Markdoc features several core concepts which include:",[792,793,794,802,816],"ul",{},[795,796,797,801],"li",{},[798,799,800],"strong",{},"Nodes:"," These are the elements that Markdoc inherits from Markdown.",[795,803,804,807,808,684,812,815],{},[798,805,806],{},"Tags:"," Tags are the main syntactic extension that Markdoc adds on top of Markdown. Similar to HTML, each tag is enclosed with ",[809,810,811],"code",{},"{%",[809,813,814],{},"%}"," and includes the tag name, attributes, and content.",[795,817,818,821],{},[798,819,820],{},"Annotations:"," These can be added to nodes to customize how they are rendered.",[674,823,824,825,690],{},"You can always view the full list of core concepts in the ",[678,826,828],{"href":778,"rel":827},[682],"syntax docs",[692,830,832],{"id":831},"what-were-building-with-nextjs-and-markdoc","What We’re Building with Next.js and Markdoc",[674,834,835],{},"We will be building a simple markdown-powered Next.js blog using Markdoc.",[674,837,838,839],{},"You can find the final result here: ",[678,840,841],{"href":841,"rel":842},"https:\u002F\u002Fmarkdoc-app.vercel.app\u002F",[682],[716,844,846],{"id":845},"prerequisites","Prerequisites",[674,848,849],{},"To follow along, you should have:",[792,851,852,860,867],{},[795,853,854,855],{},"A basic understanding of JavaScript, React, and ",[678,856,859],{"href":857,"rel":858},"https:\u002F\u002Fwww.markdownguide.org\u002Fbasic-syntax\u002F",[682],"Markdown syntax",[795,861,862],{},[678,863,866],{"href":864,"rel":865},"https:\u002F\u002Fnodejs.org\u002Fen\u002Fdownload\u002F",[682],"Node.js (latest LTS version)",[795,868,869],{},[678,870,873],{"href":871,"rel":872},"https:\u002F\u002Fcode.visualstudio.com\u002F",[682],"Visual Studio Code",[716,875,877],{"id":876},"seting-up-nextjs-with-markdoc","Seting up Next.js with Markdoc",[674,879,880,881,690],{},"Let’s follow ",[678,882,885],{"href":883,"rel":884},"https:\u002F\u002Fnextjs.org\u002Fdocs#automatic-setup",[682],"the steps to build a Next.js app",[674,887,888],{},"First, navigate to the folder of choice and run the command:",[890,891,896],"pre",{"className":892,"code":894,"language":895},[893],"language-text","npx create-next-app@latest\n# or\nyarn create next-app\n# or\npnpm create next-app\n","text",[809,897,894],{"__ignoreMap":898},"",[674,900,901,902,684,905,908],{},"Once installed, navigate to the newly created directory to install the Markdoc package. We’ll be installing ",[809,903,904],{},"@markdoc\u002Fnext.js",[809,906,907],{},"@markdoc\u002Fmarkdoc",":",[674,910,911],{},[809,912,913],{},"cd npm install @markdoc\u002Fnext.js @markdoc\u002Fmarkdoc",[674,915,916,917],{},"Next, we update our ",[809,918,919],{},"next.config.js",[890,921,924],{"className":922,"code":923,"language":895},[893],"const withMarkdoc = require('@markdoc\u002Fnext.js');\nmodule.exports = withMarkdoc(\u002F* options *\u002F)({\n pageExtensions: ['md', 'mdoc', 'js', 'jsx', 'ts', 'tsx']\n});\n",[809,925,923],{"__ignoreMap":898},[674,927,928,929,690],{},"Also, we’ll set up TailwindCSS and Tailwind Typography to style our application. To do that, we’ll follow the steps in the ",[678,930,933],{"href":931,"rel":932},"https:\u002F\u002Ftailwindcss.com\u002Fdocs\u002Fguides\u002Fnextjs",[682],"Tailwind docs",[674,935,936,937,940,941,944,945,948,949,684,952,690],{},"Install ",[809,938,939],{},"tailwindcss"," and its peer dependencies via ",[809,942,943],{},"npm",", and then run the ",[809,946,947],{},"init"," command to generate both ",[809,950,951],{},"tailwind.config.js",[809,953,954],{},"postcss.config.js",[890,956,959],{"className":957,"code":958,"language":895},[893],"npm install -D tailwindcss postcss autoprefixer @tailwindcss\u002Ftypographynpx tailwindcss init -p\n",[809,960,958],{"__ignoreMap":898},[674,962,963,964,966],{},"Add the paths to all of our template files in your ",[809,965,951],{}," file. We’ll also add the Tailwind typography plugin:",[890,968,971],{"className":969,"code":970,"language":895},[893],"\u002F\u002F .\u002Ftailwind.config.js\n\u002F** @type {import('tailwindcss').Config} *\u002F\nmodule.exports = {\n content: [\n  \".\u002Fpages\u002F**\u002F*.{js,ts,jsx,tsx}\",\n  \".\u002Fcomponents\u002F**\u002F*.{js,ts,jsx,tsx}\",\n  \".\u002Flayouts\u002F**\u002F*.{js,ts,jsx,tsx}\",\n],\ntheme: {\n  extend: {},\n },\n plugins: [require(\"@tailwindcss\u002Ftypography\")],\n};\n",[809,972,970],{"__ignoreMap":898},[674,974,975,976,979,980,983],{},"Add the ",[809,977,978],{},"@tailwind"," directives for each of Tailwind’s layers to your ",[809,981,982],{},".\u002Fstyles\u002Fglobals.css"," file.",[890,985,988],{"className":986,"code":987,"language":895},[893],"\u002F\u002F .\u002Fstyles\u002Fglobals.css\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",[809,989,987],{"__ignoreMap":898},[674,991,992,996,997,1003,996,1006,996,1009],{},[993,994,995],"em",{},"To keep this tutorial short, the styling that will be applied to this application can be accessed on"," ",[678,998,1001],{"href":999,"rel":1000},"https:\u002F\u002Fgithub.com\u002Fmiracleonyenma\u002Fmarkdoc-app\u002Fblob\u002Fmain\u002Fstyles\u002Fglobals.css",[682],[993,1002,37],{},[993,1004,1005],{},". You can copy the contents and enter them in your",[809,1007,1008],{},".\u002Fstyles.globals.css",[993,1010,1011],{},"file.",[692,1013,1015],{"id":1014},"creating-our-first-post","Creating our First Post",[674,1017,1018],{},"Create a new .md file within \u002Fpages\u002Farticles and name it getting-started.md:",[890,1020,1023],{"className":1021,"code":1022,"language":895},[893],"---\ntitle: Get started with Markdoc\ndescription: How to get started with Markdoc\n---\n# Get started with Markdoc\n",[809,1024,1022],{"__ignoreMap":898},[674,1026,1027],{},"Now, if we simply start the development server with the following command:",[890,1029,1032],{"className":1030,"code":1031,"language":895},[893],"npm run dev\n",[809,1033,1031],{"__ignoreMap":898},[674,1035,1036,1037,690],{},"We should have something like the image below when we navigate to ",[809,1038,1039],{},"\u002Farticles\u002Fgetting-started\u002F",[674,1041,1042],{},[1043,1044],"img",{"alt":1045,"src":1046},"web page showing the caption 'get started with markdoc'","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-001.png",[674,1048,1049],{},"Here, we can see that the content of our markdown file has been rendered, but it’s pretty bare.",[674,1051,1052,1053,684,1056,1059,1060,1063],{},"We need to display the data (i.e., the ",[809,1054,1055],{},"title",[809,1057,1058],{},"description",") included in the front matter of the ",[809,1061,1062],{},".md"," file:",[890,1065,1068],{"className":1066,"code":1067,"language":895},[893],"---\ntitle: Get started with Markdoc\ndescription: How to get started with Markdoc\n---\n",[809,1069,1067],{"__ignoreMap":898},[674,1071,1072],{},"The front matter data will be displayed on the article page and also added to the site’s metadata. In the following sections, we’ll cover how we can achieve that.",[692,1074,1076],{"id":1075},"creating-a-siteheader-component","Creating a SiteHeader Component",[674,1078,1079],{},"First, we have to create a global site header component which will be included in our layouts.",[674,1081,1082,1083,908],{},"Create a new file— ",[809,1084,1085],{},".\u002Fcomponents\u002FSiteHeader.jsx",[890,1087,1090],{"className":1088,"code":1089,"language":895},[893],"\u002F\u002F .\u002Fcomponents\u002FSiteHeader.jsx\nconst { default: Link } = require(\"next\u002Flink\");\nconst SiteHeader = () => {\n  return (\n                              My site                                                          Articles                       \n );\n};\nexport default SiteHeader;\n",[809,1091,1089],{"__ignoreMap":898},[674,1093,1094],{},"Next, we’ll create our layouts.",[692,1096,1098],{"id":1097},"creating-a-sitelayout-in-markdoc","Creating a SiteLayout in Markdoc",[674,1100,1101,1102,1104],{},"The layout component will be responsible for displaying all pages that are not rendered by Markdoc. We’ll also create another component which will be responsible for displaying pages rendered by Markdoc, e.g., ",[809,1103,1062],{}," files.",[674,1106,1107,1108,908],{},"Now, let’s create the layout. Create a new file ",[809,1109,1110],{},".\u002Flayouts\u002FSiteLayout.jsx",[890,1112,1115],{"className":1113,"code":1114,"language":895},[893],"\u002F\u002F .\u002Flayouts\u002FSiteLayout.jsx\nconst { default: SiteHeader } = require(\"..\u002Fcomponents\u002FSiteHeader\");\nconst SiteLayout = ({ children }) => {\n  return (\n   \u003C>\n{children}\n   \n  );\n};\nexport default SiteLayout;\n",[809,1116,1114],{"__ignoreMap":898},[692,1118,1120],{"id":1119},"creating-articlelayouts","Creating ArticleLayouts",[674,1122,1082,1123,908],{},[809,1124,1125],{},".\u002Flayouts\u002FArticleLayout.jsx",[890,1127,1130],{"className":1128,"code":1129,"language":895},[893],"\u002F\u002F .\u002Flayouts\u002FArticleLayout.jsx\nimport Head from \"next\u002Fhead\";\nimport SiteHeader from \"..\u002Fcomponents\u002FSiteHeader\";\nconst ArticleLayout = ({ markdoc, children }) => {\n  const { title, description } = markdoc?.frontmatter;\n  return (\n   \u003C>\n                     {title}        {description}                   {children}     \n   \n  );\n};\nexport default ArticleLayout;\n",[809,1131,1129],{"__ignoreMap":898},[674,1133,1134,1135,1138,1139,684,1141,1143],{},"Here, we have ",[809,1136,1137],{},"markdoc"," as a prop in this component. With that, we get ",[809,1140,1055],{},[809,1142,1058],{}," by destructuring.",[674,1145,1146,1147,684,1149,1151],{},"Using the Next.js component, we add the ",[809,1148,1055],{},[809,1150,1058],{}," to our page meta.",[674,1153,1154,1155,1158],{},"To display the data within the page, we add it to the ",[809,1156,1157],{},".article-header"," element.",[674,1160,1161,1162,1165,1166,1158],{},"Finally, to display the actual markdown content, we pass ",[809,1163,1164],{},"children"," to the ",[809,1167,1168],{},"article-content.prose",[674,1170,1171],{},"Now that we have created these components, let’s see how we can add them to our application.",[692,1173,1175],{"id":1174},"setting-up-dynamic-layouts-in-nextjs","Setting up Dynamic Layouts in Next.js",[674,1177,1178],{},"So far, we’ve created two different layouts for our application. We want to display the component on normal pages while we use the component on article pages, that is, pages rendered with Markdoc.",[674,1180,1181,1182,1185,1186,1189],{},"Next.js allows us to define layouts on a ",[993,1183,1184],{},"per-page basis"," by adding the ",[809,1187,1188],{},"getLayout"," property to our page.",[674,1191,1192,1193,1195,1196,1198,1199,1202,1203,1205],{},"Since we cannot easily add a ",[809,1194,1188],{}," property to a ",[809,1197,1062],{}," file to define which layout will be used for the page, we can define a default layout for such pages. Then ",[809,1200,1201],{},".js"," pages can define their layouts using the ",[809,1204,1188],{}," property.",[674,1207,1208,1209,1063],{},"To get this working, we’ll modify our ",[809,1210,1211],{},".\u002Fpages\u002F_app.js",[890,1213,1216],{"className":1214,"code":1215,"language":895},[893],"\u002F\u002F .\u002Fpages\u002F_app.js\nimport ArticleLayout from \"..\u002Flayouts\u002FArticleLayout\";\nimport \"..\u002Fstyles\u002Fglobals.css\";\nfunction MyApp({ Component, pageProps }) {\n \u002F\u002F configure default article layout\n const articleLayout = (page) => {\n  \u002F\u002F pass `markdoc` props to ArticleLayout\n  return (\n   page.props.markdoc && (\n {page}\n   )\n  );\n};\n\u002F\u002F Use the layout defined at the page level, if available\nconst getLayout = Component.getLayout || articleLayout;\n  return getLayout();\n}\nexport default MyApp;\n",[809,1217,1215],{"__ignoreMap":898},[674,1219,1220,1221,1224,1225,684,1228,1230],{},"In order to make the default layout, we create a function ",[809,1222,1223],{},"articleLayout()"," which accepts page as a parameter. Within this function, we return the component while passing the ",[809,1226,1227],{},"page",[809,1229,1137],{}," props.",[674,1232,1233,1234,1236,1237,1240,1241,1244],{},"Next, we initialize ",[809,1235,1188],{}," and assign the layout defined in ",[809,1238,1239],{},"Component"," (the current page) or ",[809,1242,1243],{},"articleLayout"," if the page does not define a layout.",[674,1246,1247,1248,1251],{},"Now that we’ve set up dynamic layouts in our application, let’s define the layout for our home page(",[809,1249,1250],{},".\u002Fpages\u002Findex.js","):",[890,1253,1256],{"className":1254,"code":1255,"language":895},[893],"\u002F\u002F .\u002Fpages\u002Findex.js\nimport Head from \"next\u002Fhead\";\nimport styles from \"..\u002Fstyles\u002FHome.module.css\";\nimport SiteLayout from \"..\u002Flayouts\u002FSiteLayout\";\nexport default function Home() {\n  return (\n                                      Welcome to my site      I'm glad you're here            \n  );\n}\n\u002F\u002F define layout for home page\nHome.getLayout = (page) => {\n  return  {page} ;};\n",[809,1257,1255],{"__ignoreMap":898},[674,1259,1260,1261,1264],{},"Now, if we go to ",[809,1262,1263],{},"http:\u002F\u002Flocalhost:3000"," in our browser, we should have something like this:",[674,1266,1267],{},[1043,1268],{"alt":1269,"src":1270},"welcome to my website page","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-002.png",[674,1272,1273,1274,1277],{},"Also, if we go to ",[809,1275,1276],{},"http:\u002F\u002Flocalhost:3000\u002Farticles\u002Fgetting-started",", we should see our content with the heading contained in the front matter:",[674,1279,1280],{},[1043,1281],{"alt":1282,"src":1283},"get started with markdoc webpage with a dark gray container at the top of the page","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-003.png",[692,1285,1287],{"id":1286},"building-out-the-blog","Building out the Blog",[674,1289,1290],{},"In the following sections, we’ll gradually build out our blog while exploring some of Mardoc’s features.",[674,1292,1293],{},"We’ll cover how to add custom components using tags, customize nodes, create functions, and more.",[716,1295,1297],{"id":1296},"markdoc-syntax","Markdoc syntax",[674,1299,1300,1301,690],{},"The Markdoc syntax is built on Markdown with a few additions or extensions to the syntax including nodes, tags, functions, and annotations; we’ve talked a bit about this in previous sections and you can learn all about it ",[678,1302,1304],{"href":778,"rel":1303},[682],"in their docs",[716,1306,1308],{"id":1307},"creating-custom-tags-attributes","Creating Custom Tags & Attributes",[674,1310,1311,1312,684,1314,1316,1317,1322],{},"According to the Markdoc docs, tags are the main syntactic extension that Markdoc adds on top of Markdown. Each tag is enclosed with ",[809,1313,811],{},[809,1315,814],{},", and includes the tag name, ",[678,1318,1321],{"href":1319,"rel":1320},"https:\u002F\u002Fmarkdoc.dev\u002Fdocs\u002Fsyntax#attributes",[682],"attributes",", and the content body.",[674,1324,1325,1326,1329,1330,1329,1333,1336,1337,1340,1341,1344],{},"Markdoc comes out-of-the-box with four built-in tags: ",[809,1327,1328],{},"if",", ",[809,1331,1332],{},"else",[809,1334,1335],{},"table",", and ",[809,1338,1339],{},"partial",". However, we can also create custom tags of our own. To illustrate this, we’ll create a custom ",[809,1342,1343],{},"infobox"," tag.",[674,1346,1347,1348,908],{},"First, we can create the component that will be rendered. Create a new file, ",[809,1349,1350],{},".\u002Fcomponents\u002FInfobox.jsx",[890,1352,1355],{"className":1353,"code":1354,"language":895},[893],"\u002F\u002F .\u002Fcomponents\u002FInfobox.jsx\nconst Infobox = ({ type, title, children }) => {\n  return (\n         {title}     {children}       \n  );\n};\nexport default Infobox;\n",[809,1356,1354],{"__ignoreMap":898},[674,1358,1359,1360,1363],{},"Here, we dynamically include the type value in the element class. This way, we can define styles for the ",[809,1361,1362],{},".info-box"," element depending on the type.",[716,1365,1367],{"id":1366},"creating-a-custom-infobox","Creating a Custom Infobox",[674,1369,1370,1371,1373,1374,908],{},"Next, we’ll create a custom ",[809,1372,1343],{}," tag definition in our Markdoc schema by creating a new file, ",[809,1375,1376],{},".\u002Fmarkdoc\u002Ftags\u002Finfobox.markdoc.js",[890,1378,1381],{"className":1379,"code":1380,"language":895},[893],"\u002F\u002F .\u002Fmarkdoc\u002Ftags\u002Finfobox.markdoc.js\nimport Infobox from \"..\u002F..\u002Fcomponents\u002FInfobox\";\nexport const infobox = {\n  render: Infobox,\n  attributes: {\n   type: {\n    type: String,\n    default: \"info\",\n    matches: [\"warning\", \"info\", \"error\"],\n   },\n   title: {\n    type: String,\n   },\n  },\n};\n",[809,1382,1380],{"__ignoreMap":898},[674,1384,1385,1386,1388,1389,1205],{},"Here, in our ",[809,1387,1343],{}," declaration, we import and define the component that will be rendered with the ",[809,1390,1391],{},"render",[674,1393,1394,1395,1397,1398,684,1401,690],{},"We also define the attributes that our tag accepts using the ",[809,1396,1321],{}," property and they include ",[809,1399,1400],{},"type",[809,1402,1055],{},[674,1404,1405,1406,1408,1409,1412,1413,684,1416,690],{},"For the ",[809,1407,1400],{}," attribute, we defined the type of value it accepts, the default value (",[809,1410,1411],{},"'info'",") and other acceptable matches, including ",[809,1414,1415],{},"'warning'",[809,1417,1418],{},"'error'",[674,1420,1421,1422,1425],{},"Next, we will create a ",[809,1423,1424],{},".\u002Fmarkdoc\u002Ftags\u002Findex.js"," file toexport our Markdoc tags:",[890,1427,1430],{"className":1428,"code":1429,"language":895},[893],"\u002F\u002F .\u002Fmarkdoc\u002Ftags\u002Findex.js\n\u002F* Use this file to export your markdoc tags *\u002F\nexport * from '.\u002Finfobox.markdoc';\n",[809,1431,1429],{"__ignoreMap":898},[674,1433,1434,1435,1437,1438,1441],{},"Great! With that, we can add our ",[809,1436,1343],{}," to our Markdoc document. Back in ",[809,1439,1440],{},".\u002Fpages\u002Farticles\u002Fgetting-started.md",", we’ll add some more content with our new infobox tag:",[890,1443,1446],{"className":1444,"code":1445,"language":895},[893],"---\ntitle: Get started with Markdoc\ndescription: How to get started with Markdoc\n---\n## Get started with Markdoc\nMarkdoc is a static site generator that uses Markdown files as input and outputs HTML files.\nMarkdoc features several core concepts which include:\n- **Nodes**:\n These are the elements that Markdoc inherits from Markdown\n- **Tags**:\n Tags are the main syntactic extension that Markdoc adds on top of Markdown.   Similar to HTML, each tag is enclosed with `{%` and `%}` and includes the tag name, attributes, and the content body.\n- **Annotations**:\n These can be added to nodes to customize how they are rendered\n### Installation\nTo install markdoc in Next.js, run the following command:\n```bash\nnpm install @markdoc\u002Fnext.js @markdoc\u002Fmarkdoc\n",[809,1447,1445],{"__ignoreMap":898},[716,1449,1451],{"id":1450},"background","Background",[674,1453,1454,1455,1460],{},"Markdoc was built by ",[678,1456,1459],{"href":1457,"rel":1458},"https:\u002F\u002Fstripe.com\u002F",[682],"Stripe"," to power their developer documentation.\n{%infobox title=\"Hey there!\" type=\"info\"%}\nHere's some info for you!\n{%\u002Finfobox%}\n{%infobox title=\"Hey there!\" type=\"warning\"%}\nHere's a warning for you!\n{%\u002Finfobox%}\n{%infobox title=\"Hey there!\" type=\"error\"%}\nHere's an error for you!\n{%\u002Finfobox%}",[890,1462,1465],{"className":1463,"code":1464,"language":895},[893],"\nHere, in the `{% infobox %}` tag, we define the title and type attributes for each. When we run the app, we should see something like this:\n\n![web page with red, yellow, and blue drop downs](https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-004.png)\n\nSweet! With custom Markdoc tags, we’re able to add components that can do just about anything to our `.md` files.\n\n### Customizing Default Nodes in Markdoc\n\nNext, we’ll be looking at how to customize Nodes. To illustrate this, we’ll be customizing the default blockquote node.\n\nFirst, we create a new `Blockquote` component that will be used. Create a new file: `.\u002Fcomponents\u002FBlockquote.jsx`\n\n",[809,1466,1464],{"__ignoreMap":898},[674,1468,1469],{},"\u002F\u002F .\u002Fcomponents\u002FBlockquote.jsx\nconst Blockquote = ({ children }) => {\nreturn\n{children}\n;\n};\nexport default Blockquote;\nCreate a new file: .\u002Fmarkdoc\u002Fnodes.js\n\u002F\u002F .\u002Fmarkdoc\u002Fnodes.js\nimport Blockquote from \"..\u002Fcomponents\u002FBlockquote\";\nexport const blockquote = {\nrender: Blockquote,\nattributes: {\nauthor: {\ntype: String,\n},\n}\n}",[890,1471,1474],{"className":1472,"code":1473,"language":895},[893],"\nNow, by styling the `.blockquote` class that was attached to the component, we can add the following to our article:\n\n`> Is there such an element as a \"blockquote\"?`\n\nAnd have something like this:\n\n![Existing webpage with a block quote added](https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-005.png)\n\nNow we’ve seen how to customize a node with a custom component. In the next section, we’ll take a look at another handy Markdoc feature, Partials, and how we can use variables in Markdoc.\n\n### Variables and Partials in Markdoc\n\nVariables allow us to customize your Markdoc documents at runtime. Variables are accessed using the `$` symbol.\n\nYou can pass variables in a few ways:\n\n- Through the `variables` field on the`Config` object. Also, the frontmatter of a Markdoc page can be accessed via the `$markdoc` variable in the document.\n- If we add the following to our document:\n\n`The title of this page is: **{% $markdoc.frontmatter.title %}**`\n\n- We should see the title of the document:\n\n![Existing webpage with a new line of text added to the bottom](https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-006.png)\n\n- Via the`variables` [attribute](https:\u002F\u002Fmarkdoc.dev\u002Fdocs\u002Fvariables#with-partials) on a`partial` [tag](https:\u002F\u002Fmarkdoc.dev\u002Fdocs\u002Fpartials).\n- Manually from within your`Node` or`Tag` `transform` functions.\n\nMarkdoc uses `partials` to reuse content across documents. A separate Markdoc file stores the content, and it's referenced from within the `partial` tag.\n\nWe can create a `partial` that displays a particular promotional content in any page we add it to.\n\nTo create a `partial`, create a new file, `.\u002Fmarkdoc\u002Fpartials\u002FBikePromo.md`:\n\n",[809,1475,1473],{"__ignoreMap":898},[1477,1478],"hr",{},[674,1480,1481,1482,1485],{},"It seems you’re enjoying this article on ",[798,1483,1484],{},"{% $title %}",". I'm sure you'll be interested in the following offer:",[692,1487,1489],{"id":1488},"buy-a-bike-and-get-two-wheels-free","Buy a bike and get two wheels free!",[692,1491,1493,1494,1497,1498,1501,1502,690],{"id":1492},"what-do-you-get-when-you-buy-a-biketwo-wheelswell-for-a-limited-time-only-you-can-get-two-new-bike-wheels-for-free-when-you-purchase-one-of-our-bikesfind-out-more-here-or-maybe-not-im-not-your-boss","What do you get when you buy a bike?\n",[993,1495,1496],{},"Two wheels!","\nWell, for a limited time only, you can get two new bike wheels for free when you purchase one of our bikes!\nFind out more ",[678,1499,1500],{"href":19},"here",", or maybe not, ",[993,1503,1504],{},"I'm not your boss",[890,1506,1509],{"className":1507,"code":1508,"language":895},[893],"\nPartials automatically load from the `\u002Fmarkdoc\u002Fpartials\u002F` directory. Now, if we add the following to our document:\n\n",[809,1510,1508],{"__ignoreMap":898},[674,1512,1513],{},"{% partial file=\"bike-promo.md\" \u002F%}",[890,1515,1518],{"className":1516,"code":1517,"language":895},[893],"\nIt will load and render the variables and contents of `markdoc\u002Fpartials\u002Fbike-promo.md`:\n\n![Existing webpage with added](https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-007.png)\n\nNext, we’re going to see how we can use another Markdoc feature: Functions.\n\n### Using Functions in Markdoc\n\nFunctions in Markdoc allow us to extend Markdoc with custom utilities, which lets us transform our content and [variables](https:\u002F\u002Fmarkdoc.dev\u002Fdocs\u002Fsyntax#variables) at runtime.\n\nMarkdoc comes out-of-the-box with six built-in functions: `equals`, `and`, `or`, `not`, `default`, and `debug`. You can learn more about these [functions in the Markdoc docs](https:\u002F\u002Fmarkdoc.dev\u002Fdocs\u002Ffunctions).\n\nCustom function registrations are almost identical to tags and nodes, except you create a `.\u002Fmarkdoc\u002Ffunctions.js` file instead. Within this file, we’ll create an `includes` function that checks if a string contains a defined sub-string.\n\n",[809,1519,1517],{"__ignoreMap":898},[674,1521,1522,1523,1527],{},"\u002F\u002F .\u002Fmarkdoc\u002Ffunctions.js\n\u002F\u002F .\u002Fmarkdoc\u002Ffunctions.js\nexport const includes = {\ntransform(parameters) {\nconst ",[1524,1525,1526],"span",{},"string, value"," = Object.values(parameters);\nreturn string.includes(value);\n},\n};",[890,1529,1532],{"className":1530,"code":1531,"language":895},[893],"\nNow, we can add our custom function to our document:\n\n",[809,1533,1531],{"__ignoreMap":898},[674,1535,1536],{},"{% if includes($markdoc.frontmatter.title, \"Llamas\") %}",[1538,1539,1540],"blockquote",{},[674,1541,1542],{},"This page is about Llamas\n{% else \u002F%}\nThis page is not about Llamas\n{% \u002Fif %}",[890,1544,1547],{"className":1545,"code":1546,"language":895},[893],"\nWith that, we should have something like this:\n\n![](https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-008.png)\n\nSo far, we’ve explored the basic features of Markdoc and seen how we can use it to build out an impressive article page. In the next section, we’ll quickly cover how to add images to our content.\n\n## Working with Images in Markdoc\n\nWe can simply use the markdown syntax to add any image that is in our `\u002Fpublic` directory to our article. For example, if we add the following to `.\u002Fpages\u002Farticles\u002Fgetting-started.md`:\n\n",[809,1548,1546],{"__ignoreMap":898},[674,1550,1551],{},[1043,1552],{"alt":1553,"src":1554},"image","\u002Fvercel.svg",[890,1556,1559],{"className":1557,"code":1558,"language":895},[893],"\nWe should see that the image shows up in the rendered page:\n\n![](https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-009.png)\n\nWe can also do something similar in the front matter section of the document and add a cover image for our article.\n\nTo do that, first add the path to the image in the front matter section:\n\n",[809,1560,1558],{"__ignoreMap":898},[1477,1562],{},[692,1564,1566],{"id":1565},"title-get-started-with-markdocdescription-how-to-get-started-with-markdoccover-imagesmartin-sanchez-gd3duqpmlvk-unsplashjpg","title: Get started with Markdoc\ndescription: How to get started with Markdoc\ncover: \u002Fimages\u002Fmartin-sanchez-gD3dUQpMlvk-unsplash.jpg",[890,1568,1571],{"className":1569,"code":1570,"language":895},[893],"\nNext, in `.\u002Flayouts\u002FArticleLayout.jsx`, we’ll add the image:\n\n",[809,1572,1570],{"__ignoreMap":898},[674,1574,1575,1576,1579,1580,1583,1584,1587],{},"\u002F\u002F .\u002Flayouts\u002FArticleLayout.jsx\nimport Head from \"next\u002Fhead\";\nimport Image from \"next\u002Fimage\";\nimport SiteHeader from \"..\u002Fcomponents\u002FSiteHeader\";\nconst ArticleLayout = ({ markdoc, children }) => {\nconst { title, description, cover } = markdoc.frontmatter;\nreturn (\n\u003C>\n{\u002F* ... ",[993,1577,1578],{},"\u002F}\n{\u002F"," render image ",[993,1581,1582],{},"\u002F}                     src={cover}        fill={true}        alt=\"cover\"        className=\"object-cover rounded-b-2xl\"       \u002F>            {\u002F"," ... ",[993,1585,1586],{},"\u002F}          {\u002F"," ... *\u002F}",[674,1589,1590],{},");\n};\nexport default ArticleLayout;",[890,1592,1595],{"className":1593,"code":1594,"language":895},[893],"\nWith that, we should see our image:\n\n![](https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-010.png)\n\nIn the next section, we’ll see how we can render a list of our articles.\n\n## Creating an Articles page\n\nFirst, we’ll have to install a few packages, namely:\n\n- `glob-promise` so we can find all of our Markdown files in the `articles\u002F` folder\n- `gray-matter` so we can extract the title from the Markdown frontmatter\n\nTo install, run:\n\n",[809,1596,1594],{"__ignoreMap":898},[674,1598,1599],{},"npm install gray-matter glob-promise",[890,1601,1604],{"className":1602,"code":1603,"language":895},[893],"\nNow, create a new file: `.\u002Fpages\u002Farticles\u002Findex.js`\n\n",[809,1605,1603],{"__ignoreMap":898},[674,1607,1608,1609,1612],{},"\u002F\u002F .\u002Fpages\u002Farticles\u002Findex.js\nimport fs from \"fs\";\nimport glob from \"glob-promise\";\nimport matter from \"gray-matter\";\nimport Head from \"next\u002Fhead\";\nimport Image from \"next\u002Fimage\";\nimport Link from \"next\u002Flink\";\nimport path from \"path\";\nimport SiteLayout from \"..\u002F..\u002Flayouts\u002FSiteLayout\";\nexport const getStaticProps = async () => {\n\u002F\u002F Find all Markdown files in the \u002Farticles directory\nconst ARTICLES_DIR = path.join(process.cwd(), \"pages\u002Farticles\");\nconst articlesPaths = await glob(\"**\u002F*.md\", { cwd: ARTICLES_DIR });\nconst articles = articlesPaths.map((articlePath) => {\n\u002F\u002F get the slug from the markdown file name\nconst slug = path.basename(articlePath, path.extname(articlePath));\n\u002F\u002F read the markdown files\nconst source = fs.readFileSync(\npath.join(process.cwd(), \"pages\u002Farticles\", articlePath),\n\"utf8\"\n);\n\u002F\u002F use gray-matter to parse the article frontmatter section\nconst { data } = matter(source);\nconst { title, description, cover } = data;\nreturn {\ntitle,\ndescription,\ncover,\nslug,\n};\n});\nreturn {\nprops: {\narticles,\n},\n};\n};\nconst Articles = ({ articles }) => {\nreturn (\n\u003C>\nHey there, view all my articles",[1610,1611],"br",{},"\n{articles.map((article) => (",[890,1614,1617],{"className":1615,"code":1616,"language":895},[893],"                src={article.cover}\n                width={300}\n                height={200}\n                alt=\"cover\"\n              \u002F>\n                {article.title}                     {article.description}                   \n      ))}\n",[809,1618,1616],{"__ignoreMap":898},[674,1620,1621],{},");\n};\nexport default Articles;\n\u002F\u002F define layout for articles page\nArticles.getLayout = (page) => {\nreturn  {page} ;};",[890,1623,1626],{"className":1624,"code":1625,"language":895},[893],"\nHere, we’re using `getStaticProps` to do the following:\n\n- Retrieve all of the `.md` files in the `.\u002Fpages\u002Farticles` folder\n- Read the contents of each file and obtain the `slug` and `frontmatter` data\n\nThen, we export the data and access it from our `Articles` component as `props`. We can create a list of articles with slug, title, description, and cover data.\n\n![](https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fimg-011.png)\n\nSweet!\n\n## Conclusion\n\nIn this article, we built out a blog using Markdoc and all we have to do to update our content is edit a markdown file or create a new one, save it, and redeploy.\n\nSince the content and the application live together, we do not have to go back and forth between a CMS or database in order to update our blog.\n\nWe can also add more features, like tags and sorting by date, just by including the information in the front matter of each `.md` file.\n\nThanks for going through this tutorial! I hope you learned a thing or two; feel free to keep exploring.\n\n### Further Reading and Resources\n\nHere are a few links you might find useful:\n\n#### Source Code and Live Example\n\n- [Source code on GitHub](https:\u002F\u002Fgithub.com\u002Fmiracleonyenma\u002Fmarkdoc-app)\n- [Live example hosted on Vercel](https:\u002F\u002Fmarkdoc-app.vercel.app\u002F)\n\n#### Further Reading\n\n- [Markdoc documentation](https:\u002F\u002Fmarkdoc.dev\u002Fdocs\u002Fnextjs)\n- [Using Markdoc with Next.js](https:\u002F\u002Fmarkdoc.dev\u002Fdocs\u002Fnextjs)\n",[809,1627,1625],{"__ignoreMap":898},{"title":898,"searchDepth":1629,"depth":1629,"links":1630},2,[1631,1632,1638,1642,1643,1644,1645,1646,1647,1653,1654,1656],{"id":694,"depth":1629,"text":695},{"id":710,"depth":1629,"text":711,"children":1633},[1634,1636,1637],{"id":718,"depth":1635,"text":719},3,{"id":745,"depth":1635,"text":683},{"id":760,"depth":1635,"text":761},{"id":831,"depth":1629,"text":832,"children":1639},[1640,1641],{"id":845,"depth":1635,"text":846},{"id":876,"depth":1635,"text":877},{"id":1014,"depth":1629,"text":1015},{"id":1075,"depth":1629,"text":1076},{"id":1097,"depth":1629,"text":1098},{"id":1119,"depth":1629,"text":1120},{"id":1174,"depth":1629,"text":1175},{"id":1286,"depth":1629,"text":1287,"children":1648},[1649,1650,1651,1652],{"id":1296,"depth":1635,"text":1297},{"id":1307,"depth":1635,"text":1308},{"id":1366,"depth":1635,"text":1367},{"id":1450,"depth":1635,"text":1451},{"id":1488,"depth":1629,"text":1489},{"id":1492,"depth":1629,"text":1655},"What do you get when you buy a bike?\nTwo wheels!\nWell, for a limited time only, you can get two new bike wheels for free when you purchase one of our bikes!\nFind out more here, or maybe not, I'm not your boss.",{"id":1565,"depth":1629,"text":1566},"Software Development","2023-02-14T00:00:00.000Z","In this tutorial, we’re going to build a simple yet powerful and interactive blog with Next.js and Markdoc. Let's dig in!",false,"md","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs\u002Fhero.jpeg","Image showing a person standing with the caption 'get started with markdoc'",{},"\u002Fblog\u002Fbuilding-blogs-markdoc-nextjs",{"title":665,"description":1659},"blog\u002Fbuilding-blogs-markdoc-nextjs",[1669],"nextjs-bf; blog; tutorial","qrgSiHpgXT8mqGEXOD3DvqwBUVVQxeYIXuhmXhycvQs",{"id":1672,"title":666,"body":1673,"description":898,"draft":1660,"extension":1661,"meta":1677,"navigation":32,"path":1678,"photo":1679,"photoAlt":668,"seo":1680,"stem":1681,"__hash__":1682},"authors\u002Fauthors\u002Fmiracle-onyenma.md",{"type":671,"value":1674,"toc":1675},[],{"title":898,"searchDepth":1629,"depth":1629,"links":1676},[],{},"\u002Fauthors\u002Fmiracle-onyenma","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fauthors\u002Fplaceholder.svg",{"title":666,"description":898},"authors\u002Fmiracle-onyenma","g1utsgM1Aq48grRWYDexZSVcLajpGJCVrzR7JqPsVQ4",{"left":1684,"top":1684,"width":1685,"height":1685,"rotate":1684,"vFlip":1660,"hFlip":1660,"body":1686},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>"]