[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation":3,"url-settings":86,"blog-\u002Fblog\u002Fhow-to-implement-react-infinite-scrolling-with-react-query-v5":663,"blog-author-\u002Fblog\u002Fhow-to-implement-react-infinite-scrolling-with-react-query-v5":1060,"i-material-symbols:arrow-back-rounded":1075},{"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":1047,"buttonUrl":1047,"category":1048,"date":1049,"description":1050,"draft":1051,"editorsPick":1051,"extension":1052,"featured":1051,"image":1053,"imageAlt":1054,"meta":1055,"navigation":32,"ogImage":1047,"ogImageAlt":1047,"path":1056,"seo":1057,"stem":1058,"tags":1047,"__hash__":1059},"blog\u002Fblog\u002Fhow-to-implement-react-infinite-scrolling-with-react-query-v5.md","How to Implement React Infinite Scrolling with React Query v5","James Amoo","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Ftailwind-theming-create-light-and-dark-modes\u002Fauthor.jpeg","James Amoo headshot.","james-amoo",{"type":671,"value":672,"toc":1032},"minimark",[673,677,680,683,694,697,702,710,714,732,736,739,763,767,770,773,783,786,792,806,812,827,831,840,846,853,856,860,863,870,876,882,887,930,935,944,950,964,968,975,981,984,990,999,1003,1006,1013,1016,1020,1023],[674,675,676],"p",{},"As developers, aiming for users to have the best experience when navigating your application is one of the top priorities. In addition to writing code and implementing complex functionalities, there should be a conscious effort to ensure maximum user experience and high performance of the application.",[674,678,679],{},"As a front-end developer, every bit of code, function or logic comes down to rendering content to users, so the appropriate measures should be taken in rendering content in specific use cases.",[674,681,682],{},"Consider a scenario where a huge chunk of data is to be displayed, rendering all that data to the Document Object Model (DOM) at once could have negative effects especially on the application's overall performance.",[674,684,685,686,693],{},"One way to get around this is to implement ",[687,688,692],"a",{"href":689,"rel":690},"https:\u002F\u002Fen.wiktionary.org\u002Fwiki\u002Fpagination",[691],"nofollow","pagination",", which entails creating pages and rendering a particular length of content per page. Another solution to this, one which we will discuss in this blog post, is to implementReact infinite scrolling which allows you to render more content to users only when they reach the bottom of the page.",[674,695,696],{},"In this tutorial, you will learn how to implement React infinite scrolling using React Query v5. Let's dive in!",[698,699,701],"h2",{"id":700},"react-infinite-scrolling-whats-that-about","React Infinite Scrolling - What's that about?",[674,703,704,709],{},[687,705,708],{"href":706,"rel":707},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Freact-infinite-scroll-component",[691],"Infinite scrolling"," is a content rendering technique that displays content as the user continuously scrolls to the bottom of the page. One key difference between infinite scrolling and pagination, another content rendering technique, is that infinite scrolling does not require the user to click a button to load more content. It is simply dependent on the user's action of scrolling down. Interesting, isn't it?",[698,711,713],{"id":712},"react-query","React Query",[674,715,716,720,721,726,727,731],{},[687,717,713],{"href":718,"rel":719},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Freact-query",[691]," is a JavaScript ",[687,722,725],{"href":723,"rel":724},"https:\u002F\u002Fpieces.app\u002Fblog\u002Fyou-dont-need-a-state-management-library-for-react-use-usestate-context",[691],"state management library"," used for data fetching and caching in React applications. React Query offers the ",[728,729,730],"code",{},"useInfiniteQuery"," hook which abstracts the complexities of implementing infinite scrolling in applications.",[698,733,735],{"id":734},"prerequisites","Prerequisites",[674,737,738],{},"Just before we get into the technical aspect and implementation of logic, here are a few things that would be great to know to effectively follow through this tutorial:",[740,741,742,750,757],"ul",{},[743,744,745],"li",{},[687,746,749],{"href":747,"rel":748},"https:\u002F\u002Freact.dev\u002F",[691],"React",[743,751,752],{},[687,753,756],{"href":754,"rel":755},"https:\u002F\u002Flegacy.reactjs.org\u002Fdocs\u002Fhooks-intro.html",[691],"React Hooks",[743,758,759],{},[687,760,713],{"href":761,"rel":762},"https:\u002F\u002Ftanstack.com\u002Fquery\u002Flatest\u002Fdocs\u002Fframework\u002Freact\u002Foverview",[691],[698,764,766],{"id":765},"getting-started","Getting Started",[674,768,769],{},"We're going to dive right into the logic to implement React infinite scrolling but just before we do that, let's get a few things set up in our environment.",[674,771,772],{},"Run this command in your terminal to add install React in your environment:",[774,775,780],"pre",{"className":776,"code":778,"language":779},[777],"language-text","npm create vite infinite-scroll-app react\n","text",[728,781,778],{"__ignoreMap":782},"",[674,784,785],{},"The next step will be to install the react-query library which we will be using to implement the logic. Still on your terminal, run this command:",[774,787,790],{"className":788,"code":789,"language":779},[777],"npm install react-query\n",[728,791,789],{"__ignoreMap":782},[674,793,794,795,798,799,802,803,805],{},"We're quite set on the installation bit. Now let's make some tweaks to our ",[728,796,797],{},"main.jsx"," file(this may be your ",[728,800,801],{},"index.jsx"," file if you're using another build tool). Here's what the ",[728,804,797],{}," file looks like:",[774,807,810],{"className":808,"code":809,"language":779},[777],"import * as React from \"react\";\nimport * as ReactDOM from \"react-dom\u002Fclient\";\nimport { QueryClient, QueryClientProvider } from \"react-query\";\nimport App from \".\u002FApp\";\nimport \".\u002Findex.css\";\nconst queryClient = new QueryClient();\nReactDOM.createRoot(document.getElementById(\"root\")!).render(\n);\n",[728,811,809],{"__ignoreMap":782},[674,813,814,815,818,819,822,823,826],{},"Here, we imported the ",[728,816,817],{},"QueryClientProvider"," component and the ",[728,820,821],{},"QueryClient"," instance which basically allows you to use the built-in hooks in the react-query library by wrapping your ",[728,824,825],{},"App"," component in it.",[698,828,830],{"id":829},"fetching-data","Fetching Data",[674,832,833,834,839],{},"Earlier, we discussed React query being a library for data fetching, that's the logic behind this - it controls how data is being served. To implement React infinite scrolling, we definitely have to scroll through something, some content or data of some sort. This implementation is incomplete without the presence of data. Now let's get that data! I'll be making use of the ",[687,835,838],{"href":836,"rel":837},"https:\u002F\u002Fpokeapi.co\u002F",[691],"Poke API"," which gives some mock data for our usage.",[774,841,844],{"className":842,"code":843,"language":779},[777],"const dataList = async ({\n  page,\n}) => {\n  const offset = page ? page : 0;\n  const res = await fetch(\n    `https:\u002F\u002Fpokeapi.co\u002Fapi\u002Fv2\u002Fpokemon?offset=${offset}&limit=10`\n  );\n  const data = await res.json();\n  console.log(\"data = \", data);\n  return {\n    results: data.results,\n    offset: offset + 10,\n  };\n};\nexport default dataList;\n",[728,845,843],{"__ignoreMap":782},[674,847,848,849,852],{},"Here, we're fetching our data from the API and then we set the limit to 10. The expected behavior for this is to render 10 values on the screen when the page is initially clicked upon and then continuously add more values in tens since the offset is set to ",[728,850,851],{},"offset + 10",", you can toggle this value if you want to add more values when the user reaches the bottom screen.",[674,854,855],{},"Now that we have our data fetched from the API, we can proceed to implement React infinite scrolling.",[698,857,859],{"id":858},"implement-scrolling","Implement Scrolling",[674,861,862],{},"In this section, we will get into the logic of implementing React infinite scrolling.",[674,864,865,866,869],{},"The ",[728,867,868],{},"UseInfiniteQuery"," hook",[674,871,872,873,875],{},"Here, we will use the ",[728,874,730],{}," hook from the React query library. Consider the block of code below:",[774,877,880],{"className":878,"code":879,"language":779},[777],"const {\n    data,\n    error,\n    fetchNextPage,\n    hasNextPage,\n    isFetching,\n    isLoading,\n  } = useInfiniteQuery('data', dataList, {\n    getNextPageParam: (lastPage, pages) => lastPage.offset,\n  });\n",[728,881,879],{"__ignoreMap":782},[674,883,865,884,886],{},[728,885,730],{}," hook is the foundation of this implementation as it provides properties around the:",[740,888,889,896,902,908,914,920],{},[743,890,891,895],{},[892,893,894],"strong",{},"data,"," which contains the data from the API.",[743,897,898,901],{},[892,899,900],{},"error",", which handles any error from fetching the data from the API.",[743,903,904,907],{},[892,905,906],{},"fetchNextpage",", which fetches the next set of data to be displayed when the user reaches the bottom.",[743,909,910,913],{},[892,911,912],{},"hasNextpage",", which checks to see if there's any more data to be displayed.",[743,915,916,919],{},[892,917,918],{},"isFetching",", which shows when the data is currently being fetched.",[743,921,922,925,926,929],{},[892,923,924],{},"isLoading",", which shows when the ",[892,927,928],{},"first set"," of data is being loaded from the API.",[931,932,934],"h3",{"id":933},"detecting-an-elements-position-with-intersectionobserver","Detecting an Element's Position with IntersectionObserver",[674,936,937,938,943],{},"You might have been wondering how the DOM knows when the user scrolls to the bottom of the page. Well, that's where the IntersectionObserver API comes in! The ",[687,939,942],{"href":940,"rel":941},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FIntersection_Observer_API",[691],"IntersectionObserver"," API provides a way to detect an element's position relative to the root element or viewport. Consider the block of code below:",[774,945,948],{"className":946,"code":947,"language":779},[777],"const handleObserver = useRef();\n  const lastElement = useCallback(\n    (element) => {\n      if (isLoading) return;\n      if (observer.current) handleObserver.current.disconnect();\n      handleObserver.current = new IntersectionObserver(entries => {\n        if (entries[0].isIntersecting && hasNextPage && !isFetching) {\n          fetchNextPage();\n        }\n      });\n      if (element) handleObserver.current.observe(element);\n    },\n    [isLoading, hasNextPage]\n  );\n",[728,949,947],{"__ignoreMap":782},[674,951,952,953,956,957,959,960,963],{},"This piece of code ",[892,954,955],{},"observes"," the user's motion on the screen. If the user reaches the bottom of the screen, the ",[728,958,942],{}," is alerted and serves the next set of data. Technically, it takes note of the point where the last element in the data intersects and then if ",[728,961,962],{},"hasNextPage"," is true, it fetches the new set of data to display.",[931,965,967],{"id":966},"finishing-up","Finishing up",[674,969,970,971,974],{},"The final bit of action is to render the data and logic to the DOM but just before we do that. Let's flatten the data from the API into a single array so it is easier to map through and display on the DOM. We can use React's ",[728,972,973],{},"useMemo()"," hook for this:",[774,976,979],{"className":977,"code":978,"language":779},[777],"const flatData = useMemo\n    () => (data ? data?.pages.flatMap(item => item.result) : []),\n    [data]\n);\n",[728,980,978],{"__ignoreMap":782},[674,982,983],{},"And then:",[774,985,988],{"className":986,"code":987,"language":779},[777],"if (isLoading) return \u003Ch1>Just a second...\u003C\u002Fh1>;\n\nif (error) return \u003Ch1>Oops! Something went wrong\u003C\u002Fh1>;\n\nreturn (\n    \u003Cdiv>\n        \u003Cdiv>\n            {flatData.map((item, i) => (\n                \u003Cdiv\n                    className=\"flex flex-col justify-center items-center [&>*]:my-5\"\n                    key={i}\n                    ref={flatData.length === i + 1 ? lastElement : null}\n                >\n                    \u003Ch1 className=\"text-5xl\">{item.name}\u003C\u002Fh1>\n                \u003C\u002Fdiv>\n            ))}\n        \u003C\u002Fdiv>\n        {isFetching && \u003Cdiv>Hold on...\u003C\u002Fdiv>}\n    \u003C\u002Fdiv>\n);\n",[728,989,987],{"__ignoreMap":782},[674,991,992,993,998],{},"And here we are. Added some error handling in there and ",[687,994,997],{"href":995,"rel":996},"https:\u002F\u002Ftailwindcss.com\u002F",[691],"Tailwind CSS"," styling to make the text look bigger.",[931,1000,1002],{"id":1001},"displaying-result","Displaying Result",[674,1004,1005],{},"Here's what it looks like:",[674,1007,1008],{},[1009,1010],"img",{"alt":1011,"src":1012},"List of words on a local host with React infinite scrolling.","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-implement-react-infinite-scrolling-with-react-query-v5\u002Fimg-001.gif",[674,1014,1015],{},"If you look at the scroll bar, you see that when it approaches the bottom which seems like the end, it moves up, a reaction to new data being loaded to the DOM.",[698,1017,1019],{"id":1018},"conclusion","Conclusion",[674,1021,1022],{},"In this tutorial, you have learnt about React query v5 and how to implement React infinite scrolling using React query v5. Feel free to make more tweaks and explore.",[674,1024,1025,1026,1031],{},"Stay up to date on ",[687,1027,1030],{"href":1028,"rel":1029},"https:\u002F\u002Fpieces.app\u002Fblog\u002Freact-18-a-comprehensive-guide-to-the-latest-features-and-updates",[691],"React 18"," with our comprehensive guide. Until then, Happy Coding!",{"title":782,"searchDepth":1033,"depth":1033,"links":1034},2,[1035,1036,1037,1038,1039,1040,1046],{"id":700,"depth":1033,"text":701},{"id":712,"depth":1033,"text":713},{"id":734,"depth":1033,"text":735},{"id":765,"depth":1033,"text":766},{"id":829,"depth":1033,"text":830},{"id":858,"depth":1033,"text":859,"children":1041},[1042,1044,1045],{"id":933,"depth":1043,"text":934},3,{"id":966,"depth":1043,"text":967},{"id":1001,"depth":1043,"text":1002},{"id":1018,"depth":1033,"text":1019},null,"Software Development","2024-03-01T00:00:00.000Z","Learn how to implement React infinite scrolling which allows you to render more content to users only when they reach the bottom of the page.",false,"md","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fblog\u002Fhow-to-implement-react-infinite-scrolling-with-react-query-v5\u002Fhero.jpeg","Phone and laptop.",{},"\u002Fblog\u002Fhow-to-implement-react-infinite-scrolling-with-react-query-v5",{"title":665,"description":1050},"blog\u002Fhow-to-implement-react-infinite-scrolling-with-react-query-v5","v60z7s914X_VDpS7hj9Xid_88mhik7rhBy2Igq-pNKI",{"id":1061,"title":666,"body":1062,"description":1066,"draft":1051,"extension":1052,"meta":1069,"navigation":32,"path":1070,"photo":1071,"photoAlt":1047,"seo":1072,"stem":1073,"__hash__":1074},"authors\u002Fauthors\u002Fjames-amoo.md",{"type":671,"value":1063,"toc":1067},[1064],[674,1065,1066],{},"James Amoo is a Software Engineer and a Technical Writer. He excels in creating scalable software solutions and crafting clear and concise documentation. Having graduated with a First Class Honours degree in Computer Science, he is fundamentally well-versed in the in-depth concepts of programming.",{"title":782,"searchDepth":1033,"depth":1033,"links":1068},[],{},"\u002Fauthors\u002Fjames-amoo","https:\u002F\u002Fstorage.googleapis.com\u002Fpieces-marketing-website\u002Fimages\u002Fauthors\u002Fjames-amoo.jpeg",{"title":666,"description":1066},"authors\u002Fjames-amoo","cHsg7jg2RaRueV_cvOOD8JHsrLPQxt-lYAgFPEDW_A8",{"left":1076,"top":1076,"width":1077,"height":1077,"rotate":1076,"vFlip":1051,"hFlip":1051,"body":1078},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>"]