[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation":3,"url-settings":86,"blog-\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph":663,"blog-author-\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph":1580,"i-material-symbols:arrow-back-rounded":1592},{"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":1566,"date":1567,"description":1568,"draft":1569,"editorsPick":1569,"extension":1570,"featured":1569,"image":1571,"imageAlt":1572,"meta":1573,"navigation":32,"ogImage":668,"ogImageAlt":668,"path":1574,"seo":1575,"stem":1576,"tags":1577,"__hash__":1579},"blog\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph.md","Build a Task Manager CRUD App with React and Hygraph","Jude Miracle","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fauthor.png",null,"jude-miracle",{"type":671,"value":672,"toc":1545},"minimark",[673,685,690,693,696,719,747,751,771,774,809,813,816,819,822,829,832,846,851,862,867,874,878,881,886,889,894,898,901,920,925,928,932,935,944,947,953,956,985,991,997,1014,1020,1023,1029,1033,1036,1042,1048,1054,1057,1067,1073,1077,1088,1122,1128,1134,1137,1143,1149,1156,1162,1166,1169,1179,1185,1196,1211,1217,1223,1234,1239,1245,1256,1276,1285,1290,1294,1300,1306,1336,1341,1347,1378,1381,1386,1390,1395,1401,1415,1418,1424,1427,1434,1440,1447,1453,1456,1461,1465,1470,1476,1486,1493,1499,1520,1526,1531,1535,1538],[674,675,676,677,684],"p",{},"In this article, we will introduce readers to how to build a fully functional CRUD application using Hygraph as our backend, React as our frontend, and ApolloClient to manage our state and fetch and mutate our data. We’ll leverage the Content and Mutation APIs that the Hygraph software exposes to us to perform a simple example of querying and mutating data using a task manager app: creating tasks, reading tasks, updating tasks, and finally deleting a task with ",[678,679,683],"a",{"href":680,"rel":681},"https:\u002F\u002Fblog.logrocket.com\u002Fdata-retrieval-in-graphql-with-react-apollo\u002F",[682],"nofollow","Apollo Client",". We’ll also demonstrate how to set up and manage our content and connect Hygraph to React.",[686,687,689],"h2",{"id":688},"what-is-crud","What is CRUD?",[674,691,692],{},"CRUD is an abbreviation for Create, Read, Update, and Delete. These are the four basic operations that a software application should be able to perform. These applications allow users to generate data, read data from the UI, update data, and delete data.",[674,694,695],{},"CRUD apps consist of three components in fully fledged applications:",[697,698,699,707,713],"ul",{},[700,701,702,706],"li",{},[703,704,705],"strong",{},"API (or server)",": the code and procedures.",[700,708,709,712],{},[703,710,711],{},"Database",": stores information and makes it accessible to users.",[700,714,715,718],{},[703,716,717],{},"User interface (UI):"," makes it easier for users to use the application.",[674,720,721,722,726,727,726,730,733,734,737,738,743,746],{},"When using Restful APIs to perform CRUD operations and making API requests, ",[723,724,725],"code",{},"GET",", ",[723,728,729],{},"POST",[723,731,732],{},"PUT",", and ",[723,735,736],{},"DELETE"," are the most commonly used HTTP methods. GraphQL uses two types of API requests: ",[678,739,742],{"href":740,"rel":741},"https:\u002F\u002Fgraphql.org\u002Flearn\u002Fqueries\u002F",[682],"Queries and Mutations",[703,744,745],{},"."," A query is used to read the data while mutation is used to create, update and delete the data, which we’ll do once we’ve built our task manager.",[686,748,750],{"id":749},"why-use-hygraph-for-our-task-manager","Why use Hygraph for our Task Manager?",[674,752,753,758,759,764,765,770],{},[678,754,757],{"href":755,"rel":756},"https:\u002F\u002Fgraphcms.com\u002F",[682],"Hygraph,"," formerly known as GraphCMS, is a backend-only content management system (i.e., a ",[678,760,763],{"href":761,"rel":762},"https:\u002F\u002Fpieces.app\u002Fblog\u002Fhow-to-create-sanity-headless-cms-in-nextjs",[682],"headless CMS",") that uses ",[678,766,769],{"href":767,"rel":768},"https:\u002F\u002Fgraphql.org\u002F",[682],"GraphQL"," to query data and perform mutations (or updates) to the content, making it accessible via a single endpoint (API) for display on any device without a built-in frontend or presentation layer. It allows teams to use a single content repository to deliver content from a single source to endless frontend platforms via API, such as websites, mobile apps, TVs, and so on. Hygraph also allows teams to use any preferred tech stack or framework, including popular ones like React, Angular, or Vue. It integrates easily with Netlify, Vercel, and Gatsby Cloud for quick previews.",[674,772,773],{},"To follow this tutorial, you need:",[697,775,776,783,790,798,806],{},[700,777,778],{},[678,779,782],{"href":780,"rel":781},"https:\u002F\u002Fnodejs.org\u002Fen\u002F",[682],"Node.js",[700,784,785],{},[678,786,789],{"href":787,"rel":788},"https:\u002F\u002Fwww.npmjs.com\u002F",[682],"npm",[700,791,792,793,797],{},"A ",[678,794,796],{"href":755,"rel":795},[682],"Hygraph"," account",[700,799,800,801],{},"Basic knowledge of JavaScript and ",[678,802,805],{"href":803,"rel":804},"https:\u002F\u002Freactjs.org\u002F",[682],"React",[700,807,808],{},"Basic knowledge of GraphQL",[686,810,812],{"id":811},"building-the-backend-data-structure-in-hygraph","Building the Backend Data Structure in Hygraph",[674,814,815],{},"Before you have access to the Hygraph admin panel, you’ll need to create an account (if you don’t have one already). Hygraph is simple and user-friendly, providing you with an intuitive UI and a good user experience.",[674,817,818],{},"Once you’ve signed up, create a project name, choose the region where you want your data to be stored and served, and choose a plan. For our task manager project, we are using a free forever plan.",[674,820,821],{},"From our admin dashboard, on the left, below environments, click on Schema. This will allow us to create a model. We have named our content type Task and added fields to our content.",[674,823,824],{},[825,826],"img",{"alt":827,"src":828},"","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fimg-001.png",[674,830,831],{},"Based on the image above, we created three fields:",[697,833,834,837,840],{},[700,835,836],{},"**title - (**single-line text) - The title of the task.",[700,838,839],{},"**description - (**Multi-line text) - The description of the task.",[700,841,842,845],{},[703,843,844],{},"assigned to"," - (Multi-line text) - Who the task is assigned to.",[847,848,850],"h3",{"id":849},"adding-content","Adding Content",[674,852,853,854,857,858,861],{},"Even though we can create tasks from the front end of our task manager app, we can also create new tasks from your Hygraph Admin Dashboard. Click on ",[723,855,856],{},"Content",", then ",[723,859,860],{},"Create entry",". Fill out the information.",[674,863,864],{},[825,865],{"alt":827,"src":866},"https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fimg-002.png",[674,868,869,870,873],{},"Once you have filled out the available fields, click on the ",[703,871,872],{},"save and publish"," button. You can go back and create more items.",[847,875,877],{"id":876},"hygraph-api-playground","Hygraph API Playground",[674,879,880],{},"Hygraph provides us with a GraphQL API playground where we can test our queries and perform mutation queries.",[674,882,883],{},[825,884],{"alt":827,"src":885},"https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fimg-003.png",[674,887,888],{},"You can play around with this Hygraph API environment to see the data you are querying.",[674,890,891],{},[825,892],{"alt":827,"src":893},"https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fimg-004.png",[847,895,897],{"id":896},"setting-up-roles-and-permissions","Setting up Roles and Permissions",[674,899,900],{},"Before we begin to query this data inside our React App, we must first get and set up our API endpoint and permissions to open or query any published content.",[674,902,903,904,907,908,911,912,915,916,919],{},"Go to ",[703,905,906],{},"Project settings"," > ",[703,909,910],{},"Permanent Auth Tokens > add token,"," input the name of your token, and click on ",[703,913,914],{},"add & configure permission."," Then click on ",[703,917,918],{},"Add permission"," to add permissions. With this, anybody can make a public API request without requiring authentication.",[674,921,922],{},[825,923],{"alt":827,"src":924},"https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fimg-005.png",[674,926,927],{},"Store your token somewhere secure. Later on, we’ll use it to authenticate and fetch data from our React task manager app.",[686,929,931],{"id":930},"building-our-task-manager-frontend-with-react","Building our Task Manager Frontend with React",[674,933,934],{},"In this section, we will install React and other dependencies that we will use to build our app. In your terminal, run either of the following commands:",[936,937,942],"pre",{"className":938,"code":940,"language":941},[939],"language-text","#yarnyarn create react-app project-manager && cd project-manager\n","text",[723,943,940],{"__ignoreMap":827},[674,945,946],{},"Or",[936,948,951],{"className":949,"code":950,"language":941},[939],"#npmnpx create-react-app project-manager && cd project-manager\n",[723,952,950],{"__ignoreMap":827},[674,954,955],{},"To make the development of our application easier, we will use Material-UI. This is a React UI library that adheres to Google's Material Design and offers React components right out of the box to develop our UI. In addition to the Material UI, you will need to use some libraries to connect to our backend (Hygraph):",[697,957,958,968,977],{},[700,959,960,963,964,967],{},[723,961,962],{},"graphql"," ",[703,965,966],{},"- t","his package provides logic for parsing GraphQL queries. It is used for interpreting GraphQL queries and mutations.",[700,969,970,963,973,976],{},[723,971,972],{},"apollo-client",[703,974,975],{},"-"," this is a tool that helps connect to our Hygraph GraphQL server. It’s also used to fetch, cache, and modify application data, while automatically updating your UI.",[700,978,979,963,982,984],{},[723,980,981],{},"react-router-dom",[703,983,975],{}," a library that makes it possible to integrate dynamic routing into web applications. It enables you to show pages and lets users navigate through them.",[674,986,987,988,990],{},"Run the command below to install ",[723,989,981],{}," into your React app.",[936,992,995],{"className":993,"code":994,"language":941},[939],"yarn add react-router-dom\n",[723,996,994],{"__ignoreMap":827},[674,998,999,1000,1002,1003,1006,1007,1009,1010,1013],{},"After installing ",[723,1001,981],{},", you need to make it available anywhere in your task manager app. To do this, you need to import ",[723,1004,1005],{},"BrowserRouter"," from ",[723,1008,981],{}," and then wrap the root (App) component in your ",[723,1011,1012],{},"index.js"," file.",[936,1015,1018],{"className":1016,"code":1017,"language":941},[939],"root.render(          );\n",[723,1019,1017],{"__ignoreMap":827},[674,1021,1022],{},"To install Material UI, run the command below in your terminal:",[936,1024,1027],{"className":1025,"code":1026,"language":941},[939],"yarn add @mui\u002Fmaterial @emotion\u002Freact @emotion\u002Fstyled @mui\u002Ficons-material\n",[723,1028,1026],{"__ignoreMap":827},[847,1030,1032],{"id":1031},"connecting-hygraph-to-react-using-apollo-client","Connecting Hygraph to React using Apollo Client",[674,1034,1035],{},"Install Apollo Client into our project by running the command below in your terminal:",[936,1037,1040],{"className":1038,"code":1039,"language":941},[939],"yarn add @apollo\u002Fclient graphql\n",[723,1041,1039],{"__ignoreMap":827},[674,1043,1044,1045,1047],{},"To query tasks from our Hygraph endpoint, we need to develop a GraphQL client that will make our query available across our app. This is something we can do right in the ",[723,1046,1012],{}," file:",[936,1049,1052],{"className":1050,"code":1051,"language":941},[939],"import React from 'react';\nimport ReactDOM from 'react-dom\u002Fclient';\nimport { BrowserRouter } from \"react-router-dom\"\nimport App from '.\u002FApp';\nimport { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo\u002Fclient';\nconst client = new ApolloClient({\n  uri: process.env.REACT_APP_GCMS_API,\n  cache: new InMemoryCache(),\n  headers: {\n      Authorization: `Bearer ${process.env.REACT_APP_GCMS_AUTH}`,\n    },\n});\nconst root = ReactDOM.createRoot(document.getElementById('root'));\nroot.render(\n);\n",[723,1053,1051],{"__ignoreMap":827},[674,1055,1056],{},"Here we implement the Apollo client and inject it into the application by wrapping it with the Apollo provider.",[674,1058,1059,1060,1063,1064,1066],{},"Create a file in the project’s root directory named ",[723,1061,1062],{},".env",". Add the following to ",[723,1065,1062],{},":",[936,1068,1071],{"className":1069,"code":1070,"language":941},[939],"REACT_APP_HYG_API= your api keyREACT_APP_HYG_AUTH= your api token\n",[723,1072,1070],{"__ignoreMap":827},[847,1074,1076],{"id":1075},"setting-up-routes-in-our-task-manager-backend","Setting up Routes in our Task Manager Backend",[674,1078,1079,1080,1083,1084,1087],{},"In our ",[723,1081,1082],{},"src"," folder, create a new folder called ",[723,1085,1086],{},"component",". In this components folder, we’ll create the following files:",[697,1089,1090,1098,1106,1114],{},[700,1091,1092,963,1095,1097],{},[723,1093,1094],{},"Tasks.js",[703,1096,975],{}," a template component for displaying a single task entry. We will also perform the delete and update operation on the file.",[700,1099,1100,963,1103,1105],{},[723,1101,1102],{},"TaskList.js",[703,1104,975],{}," This is apage with a list of all task data.",[700,1107,1108,963,1111,1113],{},[723,1109,1110],{},"BottomNav.js",[703,1112,975],{}," for navigating throughout the app.",[700,1115,1116,963,1119,1121],{},[723,1117,1118],{},"AddTasks.js",[703,1120,975],{}," a page with a form for adding new tasks.",[674,1123,1124,1125,1127],{},"In your ",[723,1126,1110],{}," file, add the code below:",[936,1129,1132],{"className":1130,"code":1131,"language":941},[939],"import { AddTask, Task } from '@mui\u002Ficons-material';\nimport { BottomNavigation, BottomNavigationAction } from '@mui\u002Fmaterial';\nimport React, { useState } from 'react'\nconst BottomNav = () => {\n  const [value, setValue] = useState('task');\n  return (\n                    showLabels            sx={{bgcolor: '#292f38'}}            value={value}            onChange={(event, newValue) => {              setValue(newValue);            }}        >          } \u002F>          } \u002F>          \n  )\n}\nexport default BottomNav\n",[723,1133,1131],{"__ignoreMap":827},[674,1135,1136],{},"We use Material UI to create navigation in our task manager that allows us to navigate through the list of tasks as well as creating a task.",[936,1138,1141],{"className":1139,"code":1140,"language":941},[939],"import React from 'react';\nimport { Route, Routes } from \"react-router-dom\";\nimport AddTask from '.\u002Fcomponents\u002FAddTask';\nimport TaskList from '.\u002Fcomponents\u002FTaskList';\nimport BottomNav from '.\u002Fcomponents\u002FBottomNav';\nimport '.\u002FApp.css'\nfunction App() {\n  return (\n                              Task Manager                                              } \u002F>               } \u002F>                                              \n  );\n}\nexport default App;\n",[723,1142,1140],{"__ignoreMap":827},[674,1144,1145,1146,1148],{},"Here, we used features from the ",[723,1147,981],{}," library to define our routes and their paths and attach them to their respective components.",[674,1150,1151,1152,1155],{},"We have added additional styles to our application. Update your ",[723,1153,1154],{},"App.css"," with the code below:",[936,1157,1160],{"className":1158,"code":1159,"language":941},[939],"* {\n  margin: 0;\n  padding: 0;\n}\n.container {\n  background: linear-gradient(100deg, rgb(182, 40, 111) 50%, #ac2066 0);\n  width: 100%;\n  padding: 20px;\n  height: 100vh;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n.app-wrapper {\n  background-color: #292f38;\n  width: 30%;\n  min-width: 800px;\n  height: 600px;\n  padding: 30px;\n  box-sizing: border-box;\n  border-radius: 5px;\n  box-shadow: 0 15px 30px rgba(0, 0, 0, 0.4);\n}\n.header h1 {\n  color: #ccc;\n  font-weight: 300;\n  text-align: center;\n  margin: 50px 20px 60px 20px;\n  font-family: 'Josefin Slab', serif;\n}\n.main {\n  display: flex;\n  flex-direction: column;\n  align-items: space-between;\n  margin-bottom: 50px;\n  width: 100%;\n}\n.list {\n  width: 90%;\n  margin: auto;\n  max-height: 300px;\n  overflow: hidden;\n  overflow-y: auto;\n}\n\u002F* width *\u002F\n::-webkit-scrollbar {\n  width: 10px;\n}\n\u002F* Track *\u002F\n::-webkit-scrollbar-track {\n  border-radius: 10px;\n  background-color: #aaa;\n}\n\u002F* Handle *\u002F\n::-webkit-scrollbar-thumb {\n  background: #444;\n  border-radius: 10px;\n}\n.list-item {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin: 20px 0;\n  padding-bottom: 5px;\n}\n.list-item span {\n  color: #999;\n}\n.list-item h2 {\n  color: #999;\n}\n.no-tasks {\n  color: #777;\n  text-align: center;\n  font-size: 18px;\n  margin-top: 20px;\n}\n",[723,1161,1159],{"__ignoreMap":827},[847,1163,1165],{"id":1164},"querying-content-and-displaying-tasks-in-our-task-manager","Querying Content and Displaying Tasks in our Task Manager",[674,1167,1168],{},"Let’s start by creating a file that we’ll use to store all of our queries and mutation queries. The goal is to migrate all of our code with a simple copy of the file. By doing so, we can manage our API-specific interactions in a single file, edit and update code, and reuse it between files.",[674,1170,1171,1172,1174,1175,1178],{},"In the ",[723,1173,1082],{}," folder, create a ",[723,1176,1177],{},"lib\u002Fapi.js"," file and add the following code:",[936,1180,1183],{"className":1181,"code":1182,"language":941},[939],"import { gql } from '@apollo\u002Fclient';\n\u002F\u002F getting all tasks\nexport const ALL_TASK = gql`\n    query {\n        tasks(stage: DRAFT) {\n            id\n            title\n            description\n            assignedTo\n        }\n    }\n`\n",[723,1184,1182],{"__ignoreMap":827},[674,1186,1187,1188,1191,1192,1195],{},"We used ",[723,1189,1190],{},"gql",", a function for passing queries from the Apollo client library that we imported from the Apollo client, to wrap and define the query we want to execute. In our query, we passed a variable ",[703,1193,1194],{},"DRAFT"," because we also want to fetch the task in the draft. We are doing this because we won’t perform the published task operation from our front end in this tutorial.",[674,1197,1198,963,1202,963,1208],{},[1199,1200,1201],"em",{},"Publishing tasks from the front end without going to the Hygraph dashboard is possible. Read the",[678,1203,1206],{"href":1204,"rel":1205},"https:\u002F\u002Fhygraph.com\u002Fdocs\u002Fapi-reference\u002Fcontent-api\u002Fmutations",[682],[1199,1207,796],{},[1199,1209,1210],{},"documentation to learn how.",[674,1212,1124,1213,1216],{},[723,1214,1215],{},"components\u002FTasks.js"," file, add the following code:",[936,1218,1221],{"className":1219,"code":1220,"language":941},[939],"import React  from 'react'\nimport {AssignmentInd, Delete, Description, Update} from '@mui\u002Ficons-material';\nimport { List, ListItemButton, ListItemIcon, ListItemText, Typography, Stack, Button, Modal, Box, FormControl, OutlinedInput, InputLabel } from '@mui\u002Fmaterial';\nconst Task = ({ task, getTask }) => {\n  return (\n        \n        >\n            {task.title}\n                \n                sx={{bgcolor: '#292f38', color: '#ccc'}}\n                \u002F>\n                \n                sx={{bgcolor: '#292f38', color: '#ccc'}}\n                \u002F>\n  )\n}\nexport default Task\n",[723,1222,1220],{"__ignoreMap":827},[674,1224,1225,1226,1229,1230,1233],{},"We used Material UI to build out our front end where we display the title, description, and assignee of each task. We pass ",[723,1227,1228],{},"task"," and ",[723,1231,1232],{},"getTask"," as props.",[674,1235,1124,1236,1216],{},[723,1237,1238],{},"component\u002FTaskList.js",[936,1240,1243],{"className":1241,"code":1242,"language":941},[939],"import React from 'react'\nimport { useQuery } from '@apollo\u002Fclient';\nimport { ALL_TASK } from '..\u002Flib\u002Fapi';\nimport Task from '.\u002FTask';\nimport { Typography } from '@mui\u002Fmaterial';\nconst TaskList = () => {\n  const { loading, error, data } = useQuery(ALL_TASK)\n  if (loading) return \nGetting tasks...\n;  if (error) return \nAn error occurred\n;\n  return (\n                    Total Tasks: {data.tasks.length}                {data.tasks.length ?            (                                    {data.tasks.map((task) => (                                            ))}                            )            :            (                No Tasks            )        }    \n  )\n}\nexport default TaskList;\n",[723,1244,1242],{"__ignoreMap":827},[674,1246,1247,1248,1251,1252,1255],{},"We imported the ",[723,1249,1250],{},"useQuery"," hook provided by the Apollo client and we passed the ",[723,1253,1254],{},"ALL_TASK GraphQL"," query to it. We defined three states for the data in our hook.",[697,1257,1258,1264,1270],{},[700,1259,1260,1263],{},[723,1261,1262],{},"loading"," - this is helpful while the query is being processed.",[700,1265,1266,1269],{},[723,1267,1268],{},"error"," - when the query was unsuccessfully processed.",[700,1271,1272,1275],{},[723,1273,1274],{},"data"," - this contains data returned by Hygrapyh.",[674,1277,1278,1279,1281,1282,1284],{},"Inside the ",[723,1280,1274],{},"object, we now have access to the tasks*.* When the application renders the component, the ",[723,1283,1250],{}," hook will be called.",[674,1286,1287],{},[825,1288],{"alt":827,"src":1289},"https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fimg-006.png",[686,1291,1293],{"id":1292},"creating-new-tasks-with-mutation","Creating New Tasks with Mutation",[674,1295,1296,1297,1299],{},"To create a task in your task manager, in your ",[723,1298,1177],{}," file, add the query below:",[936,1301,1304],{"className":1302,"code":1303,"language":941},[939],"export const CREATE_TASK =  gql`\n    mutation CreateTask($assignedTo: String, $description: String, $title: String) {\n        createTask(\n            data: {assignedTo: $assignedTo, description: $description, title: $title}\n          ) {\n            id\n            title\n            description\n            assignedTo\n        }\n    }\n`\n",[723,1305,1303],{"__ignoreMap":827},[674,1307,1308,1309,1312,1313,1316,1317,1320,1321,1324,1325,1328,1329,1332,1333,1335],{},"Before now, we’ve been calling the backend for data using ",[703,1310,1311],{},"queries."," We now want to play around with them a bit, but to do so, we need to employ ",[703,1314,1315],{},"mutations",". To perform the CRUD operations create, update, and delete, we used mutation as an operation type. We export the ",[723,1318,1319],{},"CREATE_TASK"," query; when we build a new model, Hygraph automatically provides a custom function called ",[723,1322,1323],{},"create__"," for us. The name of the model to be created is always prefixed to it. The ",[723,1326,1327],{},"createTask"," function was necessary because our model was given the name ",[723,1330,1331],{},"Task",". Use ",[723,1334,1327],{},"as an operation name and pass on our variables that are required by the backend.",[674,1337,1124,1338,1127],{},[723,1339,1340],{},"AddTask.js",[936,1342,1345],{"className":1343,"code":1344,"language":941},[939],"import React, { useState } from 'react'\nimport { useMutation } from '@apollo\u002Fclient'\nimport { CREATE_TASK } from '..\u002Flib\u002Fapi';\nimport {OutlinedInput, FormControl, InputLabel, Button, Box} from '@mui\u002Fmaterial'\nconst AddTask = () => {\n  const [task, setTask] = useState({});\n  const [createTask, { isadding }] = useMutation(CREATE_TASK)\n  if (isadding) return 'Submitting...';\n  const handleOnChange = (event)=> {\n    setTask({ ...task, [event.target.name]: event.target.value});\n  }\n  const onClick = () => {\n    createTask({variables: { ...task }});\n  }\n  return (\n    \n    sx={{ maxWidth: '100%'}}>\nTitle\n        \n          onChange={handleOnChange}\n          name='title'\n          label=\"title\"\n          sx={{border: '1px solid #cccc'}}\n        \u002F>\nDescription\n         \n          onChange={handleOnChange}\n          name='description'\n          label=\"description\"\n          sx={{border: '1px solid #cccc'}}\n        \u002F>\nAssigned To\n        \n          onChange={handleOnChange}\n          name='assignedTo'\n          label=\"Assigned To\"\n          sx={{border: '1px solid #cccc'}}\n        \u002F>\nAdd Task    \n  )\n}\nexport default AddTask\n",[723,1346,1344],{"__ignoreMap":827},[674,1348,1349,1350,1353,1354,1357,1358,1360,1361,1363,1364,1366,1367,1369,1370,1373,1374,1377],{},"First, we used the ",[723,1351,1352],{},"useState"," hook from React to store the provided state. We then used the ",[723,1355,1356],{},"useMutation"," hook from the Apollo client. The ",[723,1359,1356],{}," hook depends on the ",[723,1362,1327],{}," function to execute the ",[723,1365,1319],{}," mutation query. If the ",[723,1368,1327],{}," function gets called, the mutation gets executed. We then use the ",[723,1371,1372],{},"handleOnChange"," function to update the ",[723,1375,1376],{},"state"," whenever the user inputs data.",[674,1379,1380],{},"After entering dummy content and clicking on Add task in our task manager, if all goes well, a new task will be created and you will be able to view your content in the Hygraph Dashboard. Newly created tasks don’t automatically get published unless we call the publish function or publish it from the dashboard. But, we already defined our query to also fetch content from the draft, so newly created content will automatically be displayed on our front end.",[674,1382,1383],{},[825,1384],{"alt":827,"src":1385},"https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fimg-007.png",[847,1387,1389],{"id":1388},"updating-tasks-in-our-task-manager","Updating Tasks in our Task Manager",[674,1391,1392,1393,1299],{},"It's easy to update posts by simply adding new content to existing content and updating the Hygraph store. In our ",[723,1394,1177],{},[936,1396,1399],{"className":1397,"code":1398,"language":941},[939],"export const UPDATE_TASk = gql`\n    mutation UpdateTask($assignedTo: String, $description: String, $title: String, $id: ID){\n        updateTask(\n            where: {id: $id}\n            data: {assignedTo: $assignedTo, description: $description, title: $title}\n        ) {\n            assignedTo\n            description\n            title\n        }\n}\n`\n",[723,1400,1398],{"__ignoreMap":827},[674,1402,1403,1404,1407,1408,1411,1412,1414],{},"Updating entities using mutations is similar to creating new ones, except you need two arguments in your query: the ",[723,1405,1406],{},"where"," object referencing the ",[723,1409,1410],{},"id"," of the task you want to update and the ",[723,1413,1274],{}," object that holds the data to replace the old content.",[674,1416,1417],{},"We'll need a form to collect the data we'll need to update a task. We’ll create a modal so that when a user tries to update a task by clicking on the update icon, it will call up a modal containing the form.",[936,1419,1422],{"className":1420,"code":1421,"language":941},[939],"const [open, setOpen] = useState(false);\nconst handleOpen = () => setOpen(true);\nconst handleClose = () => setOpen(false);\nconst [replacementTask, setReplacementTask] = useState({});\nconst handleOnChange = (event)=> {\n    setReplacementTask({ ...replacementTask, [event.target.name]: event.target.value });\n}\nconst [updateTask] = useMutation(UPDATE_TASk, {\n    refetchQueries: [\n        { query: getTask },\n    ]\n});\nconst handleUpdate = () => {\n    updateTask({ variables: { id: task.id, ...replacementTask }})\n}\n",[723,1423,1421],{"__ignoreMap":827},[674,1425,1426],{},"To better control the process of creating and updating content, we define several states. We then define functions that are responsible for handling form input and calling the Hygraph API services in our query.",[674,1428,1429,1430,1433],{},"Add the ",[723,1431,1432],{},"handleOpen"," function to the Update icon:",[936,1435,1438],{"className":1436,"code":1437,"language":941},[939],"    sx={{bgcolor: '#292f38', color: '#ccc'}}\n    onClick={handleOpen}\n    \u002F>\n",[723,1439,1437],{"__ignoreMap":827},[674,1441,1442,1443,1446],{},"With this, when you click on the update button a modal will pop up containing the form field. Now below the ",[723,1444,1445],{},"Button"," container, add the modal component from Material UI to build our form field.",[936,1448,1451],{"className":1449,"code":1450,"language":941},[939],"      aria-describedby=\"modal-modal-description\">\nTitle\n        \n            onChange={handleOnChange}\n            name='title'\n            label=\"Title\"\n            sx={{color: '#cccc'}}\n        \u002F>\nDescription\n        \n            onChange={handleOnChange}\n            name='description'\n            label=\"Description\"\n            sx={{color: '#cccc'}}\n         \u002F>\nAssigned To\n        \n            onChange={handleOnChange}\n            name='assignedTo'\n            label=\"Assigned To\"\n            sx={{color: '#cccc'}}\n        \u002F>\n      onClick={handleUpdate}     type='submit'>Update\n",[723,1452,1450],{"__ignoreMap":827},[674,1454,1455],{},"With this, we can now successfully update our task. You will have to republish the task after editing it from the Hygraph dashboard.",[674,1457,1458],{},[825,1459],{"alt":827,"src":1460},"https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fimg-008.png",[847,1462,1464],{"id":1463},"deleting-tasks","Deleting Tasks",[674,1466,1467,1468,1216],{},"In this section, we’ll work on deleting each task from the front end of our task manager. In our ",[723,1469,1177],{},[936,1471,1474],{"className":1472,"code":1473,"language":941},[939],"export const DELETE_TASK = gql`\n    mutation DeleteTask($id: ID!) {\n        deleteTask(where: {id: $id}) {\n            id\n            title\n            description\n            assignedTo\n        }\n    }\n`\n",[723,1475,1473],{"__ignoreMap":827},[674,1477,1478,1479,1482,1483,1485],{},"Here, we define the ",[723,1480,1481],{},"DELETE_TASK"," that we used to delete our task, and referenced the ",[723,1484,1410],{}," variable of the task to be deleted.",[674,1487,1488,1489,1492],{},"Update your ",[723,1490,1491],{},"component\u002FTask.js"," file with the following code:",[936,1494,1497],{"className":1495,"code":1496,"language":941},[939],"const [deleteTask] = useMutation(DELETE_TASK, {\n    refetchQueries: [\n        { query: getTask },\n    ]\n})\nconst handleDelete = () => {\n    deleteTask({ variables: { id: task.id }});\n}\n",[723,1498,1496],{"__ignoreMap":827},[674,1500,1501,1502,1505,1506,1508,1509,1512,1513,1516,1517,1519],{},"We also added the property ",[723,1503,1504],{},"refetchQueries"," supplied by the ",[723,1507,1356],{}," hook to re-fetch our data to reflect the modifications brought on by deleting a task. We called the ",[723,1510,1511],{},"deleteTask"," function with the ",[723,1514,1515],{},"handleDelete"," function and passed the data of the ",[723,1518,1410],{}," to the variable we defined.",[936,1521,1524],{"className":1522,"code":1523,"language":941},[939],"    sx={{bgcolor: '#292f38', color: '#ccc'}}\n      onClick={handleDelete}\n    \u002F>\n",[723,1525,1523],{"__ignoreMap":827},[674,1527,1528],{},[825,1529],{"alt":827,"src":1530},"https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fimg-009.png",[686,1532,1534],{"id":1533},"conclusion","Conclusion",[674,1536,1537],{},"In this tutorial, we learned about the Hygraph headless CMS and how to use Hygraph to create a model, manage content, and set up roles and permissions. Using Hygraph, Apollo Client, React Router Dom, Material UI, and React, we were able to develop a fully functional CRUD task manager application.",[674,1539,1540,1541,745],{},"You can find the source code for this article on ",[678,1542,37],{"href":1543,"rel":1544},"https:\u002F\u002Fgithub.com\u002Fam-miracle\u002FHygraph-Task-Manager",[682],{"title":827,"searchDepth":1546,"depth":1546,"links":1547},2,[1548,1549,1550,1556,1561,1565],{"id":688,"depth":1546,"text":689},{"id":749,"depth":1546,"text":750},{"id":811,"depth":1546,"text":812,"children":1551},[1552,1554,1555],{"id":849,"depth":1553,"text":850},3,{"id":876,"depth":1553,"text":877},{"id":896,"depth":1553,"text":897},{"id":930,"depth":1546,"text":931,"children":1557},[1558,1559,1560],{"id":1031,"depth":1553,"text":1032},{"id":1075,"depth":1553,"text":1076},{"id":1164,"depth":1553,"text":1165},{"id":1292,"depth":1546,"text":1293,"children":1562},[1563,1564],{"id":1388,"depth":1553,"text":1389},{"id":1463,"depth":1553,"text":1464},{"id":1533,"depth":1546,"text":1534},"Software Development","2023-02-17T00:00:00.000Z","Let's build a fully functional CRUD application using Hygraph, React, and ApolloClient. The task manager we'll have at the end will help you stay organized!",false,"md","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph\u002Fhero.jpeg","decorative cover image showing crud task manager",{},"\u002Fblog\u002Fbuild-crud-task-manager-react-hygraph",{"title":665,"description":1568},"blog\u002Fbuild-crud-task-manager-react-hygraph",[1578],"tutorial; productivity-e","UVj1BUQ05qnwYc_HTqlvLhXuNGry4BYlutMHsR9TRho",{"id":1581,"title":666,"body":1582,"description":827,"draft":1569,"extension":1570,"meta":1586,"navigation":32,"path":1587,"photo":1588,"photoAlt":668,"seo":1589,"stem":1590,"__hash__":1591},"authors\u002Fauthors\u002Fjude-miracle.md",{"type":671,"value":1583,"toc":1584},[],{"title":827,"searchDepth":1546,"depth":1546,"links":1585},[],{},"\u002Fauthors\u002Fjude-miracle","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fauthors\u002Fjude-miracle.jpg",{"title":666,"description":827},"authors\u002Fjude-miracle","ulvEZJgJ78pdy0UIdxijTf2zwj7EA0CDHd9ajwUZ5Lc",{"left":1593,"top":1593,"width":1594,"height":1594,"rotate":1593,"vFlip":1569,"hFlip":1569,"body":1595},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>"]