[{"data":1,"prerenderedAt":648},["ShallowReactive",2],{"navigation":3,"-guide-next":48,"-guide-next-surround":643},[4],{"title":5,"path":6,"stem":7,"children":8,"icon":47},"Guide","\u002Fguide","1.guide\u002F1.index",[9,12,17,22,27,32,37,42],{"title":10,"path":6,"stem":7,"icon":11},"Getting started","i-lucide-rocket",{"title":13,"path":14,"stem":15,"icon":16},"Nuxt","\u002Fguide\u002Fnuxt","1.guide\u002F2.nuxt","i-logos-nuxt-icon",{"title":18,"path":19,"stem":20,"icon":21},"Next.js","\u002Fguide\u002Fnext","1.guide\u002F3.next","i-logos-nextjs-icon",{"title":23,"path":24,"stem":25,"icon":26},"How it works","\u002Fguide\u002Fhow-it-works","1.guide\u002F4.how-it-works","i-lucide-workflow",{"title":28,"path":29,"stem":30,"icon":31},"Options","\u002Fguide\u002Foptions","1.guide\u002F5.options","i-lucide-settings",{"title":33,"path":34,"stem":35,"icon":36},"API","\u002Fguide\u002Fapi","1.guide\u002F6.api","i-lucide-code",{"title":38,"path":39,"stem":40,"icon":41},"Privacy","\u002Fguide\u002Fprivacy","1.guide\u002F7.privacy","i-lucide-lock",{"title":43,"path":44,"stem":45,"icon":46},"Benchmarks","\u002Fguide\u002Fbenchmarks","1.guide\u002F8.benchmarks","i-lucide-gauge","i-lucide-book-open",{"id":49,"title":18,"body":50,"description":637,"extension":638,"meta":639,"navigation":640,"path":19,"seo":641,"stem":20,"__hash__":642},"content\u002F1.guide\u002F3.next.md",{"type":51,"value":52,"toc":628,"icon":21},"minimark",[53,60,65,69,97,112,116,119,174,185,189,393,398,458,462,465,472,496,514,517,521,527,531,606,610,624],[54,55,56],"note",{},[57,58,59],"p",{},"App Router only. The Pages Router needs a different API route and a different prefetch call,\nand is not supported yet.",[61,62,64],"h2",{"id":63},"install","Install",[66,67],"pm-install",{"name":68},"next-precog",[70,71,77],"pre",{"className":72,"code":73,"filename":74,"language":75,"meta":76,"style":76},"language-sh shiki shiki-themes github-light github-dark github-dark","TYPESAFE_API_KEY=\"your-api-key\"\n",".env","sh","",[78,79,80],"code",{"__ignoreMap":76},[81,82,85,89,93],"span",{"class":83,"line":84},"line",1,[81,86,88],{"class":87},"slsVL","TYPESAFE_API_KEY",[81,90,92],{"class":91},"so5gQ","=",[81,94,96],{"class":95},"sfrk1","\"your-api-key\"\n",[57,98,99,100,107,108,111],{},"Using a ",[101,102,106],"a",{"href":103,"rel":104},"https:\u002F\u002Fvercel.com\u002Fdocs\u002Fai-gateway",[105],"nofollow","Vercel AI Gateway"," key? Name it\n",[78,109,110],{},"AI_GATEWAY_API_KEY"," and the handler routes through the gateway on its own.",[61,113,115],{"id":114},"the-route-handler","The route handler",[57,117,118],{},"The key stays on the server, which is the whole reason this route exists.",[70,120,125],{"className":121,"code":122,"filename":123,"language":124,"meta":76,"style":76},"language-ts shiki shiki-themes github-light github-dark github-dark","import { createPrecogHandler } from \"next-precog\u002Fserver\";\n\nexport const POST = createPrecogHandler();\n","app\u002Fapi\u002Fprecog\u002Froute.ts","ts",[78,126,127,144,151],{"__ignoreMap":76},[81,128,129,132,135,138,141],{"class":83,"line":84},[81,130,131],{"class":91},"import",[81,133,134],{"class":87}," { createPrecogHandler } ",[81,136,137],{"class":91},"from",[81,139,140],{"class":95}," \"next-precog\u002Fserver\"",[81,142,143],{"class":87},";\n",[81,145,147],{"class":83,"line":146},2,[81,148,150],{"emptyLinePlaceholder":149},true,"\n",[81,152,154,157,160,164,167,171],{"class":83,"line":153},3,[81,155,156],{"class":91},"export",[81,158,159],{"class":91}," const",[81,161,163],{"class":162},"suiK_"," POST",[81,165,166],{"class":91}," =",[81,168,170],{"class":169},"shcOC"," createPrecogHandler",[81,172,173],{"class":87},"();\n",[57,175,176,177,180,181,184],{},"It validates the body itself, rate limits per caller, caches in process, and answers ",[78,178,179],{},"503"," with\nan empty prediction on any failure, with the reason in ",[78,182,183],{},"x-precog-reason",".",[61,186,188],{"id":187},"the-provider","The provider",[70,190,195],{"className":191,"code":192,"filename":193,"language":194,"meta":76,"style":76},"language-tsx shiki shiki-themes github-light github-dark github-dark","import { PrecogProvider, PrecogOverlay } from \"next-precog\";\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n  return (\n    \u003Chtml lang=\"en\">\n      \u003Cbody>\n        \u003CPrecogProvider>\n          {children}\n          {process.env.NODE_ENV === \"development\" ? \u003CPrecogOverlay \u002F> : null}\n        \u003C\u002FPrecogProvider>\n      \u003C\u002Fbody>\n    \u003C\u002Fhtml>\n  );\n}\n","app\u002Flayout.tsx","tsx",[78,196,197,211,215,259,268,289,300,311,317,352,362,372,382,388],{"__ignoreMap":76},[81,198,199,201,204,206,209],{"class":83,"line":84},[81,200,131],{"class":91},[81,202,203],{"class":87}," { PrecogProvider, PrecogOverlay } ",[81,205,137],{"class":91},[81,207,208],{"class":95}," \"next-precog\"",[81,210,143],{"class":87},[81,212,213],{"class":83,"line":146},[81,214,150],{"emptyLinePlaceholder":149},[81,216,217,219,222,225,228,231,235,238,241,244,246,248,251,253,256],{"class":83,"line":153},[81,218,156],{"class":91},[81,220,221],{"class":91}," default",[81,223,224],{"class":91}," function",[81,226,227],{"class":169}," RootLayout",[81,229,230],{"class":87},"({ ",[81,232,234],{"class":233},"sQHwn","children",[81,236,237],{"class":87}," }",[81,239,240],{"class":91},":",[81,242,243],{"class":87}," { ",[81,245,234],{"class":233},[81,247,240],{"class":91},[81,249,250],{"class":169}," React",[81,252,184],{"class":87},[81,254,255],{"class":169},"ReactNode",[81,257,258],{"class":87}," }) {\n",[81,260,262,265],{"class":83,"line":261},4,[81,263,264],{"class":91},"  return",[81,266,267],{"class":87}," (\n",[81,269,271,274,278,281,283,286],{"class":83,"line":270},5,[81,272,273],{"class":87},"    \u003C",[81,275,277],{"class":276},"sByVh","html",[81,279,280],{"class":169}," lang",[81,282,92],{"class":91},[81,284,285],{"class":95},"\"en\"",[81,287,288],{"class":87},">\n",[81,290,292,295,298],{"class":83,"line":291},6,[81,293,294],{"class":87},"      \u003C",[81,296,297],{"class":276},"body",[81,299,288],{"class":87},[81,301,303,306,309],{"class":83,"line":302},7,[81,304,305],{"class":87},"        \u003C",[81,307,308],{"class":162},"PrecogProvider",[81,310,288],{"class":87},[81,312,314],{"class":83,"line":313},8,[81,315,316],{"class":87},"          {children}\n",[81,318,320,323,326,329,332,335,338,341,344,346,349],{"class":83,"line":319},9,[81,321,322],{"class":87},"          {process.env.",[81,324,325],{"class":162},"NODE_ENV",[81,327,328],{"class":91}," ===",[81,330,331],{"class":95}," \"development\"",[81,333,334],{"class":91}," ?",[81,336,337],{"class":87}," \u003C",[81,339,340],{"class":162},"PrecogOverlay",[81,342,343],{"class":87}," \u002F> ",[81,345,240],{"class":91},[81,347,348],{"class":162}," null",[81,350,351],{"class":87},"}\n",[81,353,355,358,360],{"class":83,"line":354},10,[81,356,357],{"class":87},"        \u003C\u002F",[81,359,308],{"class":162},[81,361,288],{"class":87},[81,363,365,368,370],{"class":83,"line":364},11,[81,366,367],{"class":87},"      \u003C\u002F",[81,369,297],{"class":276},[81,371,288],{"class":87},[81,373,375,378,380],{"class":83,"line":374},12,[81,376,377],{"class":87},"    \u003C\u002F",[81,379,277],{"class":276},[81,381,288],{"class":87},[81,383,385],{"class":83,"line":384},13,[81,386,387],{"class":87},"  );\n",[81,389,391],{"class":83,"line":390},14,[81,392,351],{"class":87},[57,394,395,397],{},[78,396,308],{}," takes the same options as the Nuxt module, as props:",[70,399,401],{"className":191,"code":400,"language":194,"meta":76,"style":76},"\u003CPrecogProvider\n  mode=\"auto\"\n  endpoint=\"\u002Fapi\u002Fprecog\"\n  thresholds={{ prefetch: 0.25, prerender: 0.6 }}\n\u002F>\n",[78,402,403,411,421,431,453],{"__ignoreMap":76},[81,404,405,408],{"class":83,"line":84},[81,406,407],{"class":87},"\u003C",[81,409,410],{"class":162},"PrecogProvider\n",[81,412,413,416,418],{"class":83,"line":146},[81,414,415],{"class":169},"  mode",[81,417,92],{"class":91},[81,419,420],{"class":95},"\"auto\"\n",[81,422,423,426,428],{"class":83,"line":153},[81,424,425],{"class":169},"  endpoint",[81,427,92],{"class":91},[81,429,430],{"class":95},"\"\u002Fapi\u002Fprecog\"\n",[81,432,433,436,438,441,444,447,450],{"class":83,"line":261},[81,434,435],{"class":169},"  thresholds",[81,437,92],{"class":91},[81,439,440],{"class":87},"{{ prefetch: ",[81,442,443],{"class":162},"0.25",[81,445,446],{"class":87},", prerender: ",[81,448,449],{"class":162},"0.6",[81,451,452],{"class":87}," }}\n",[81,454,455],{"class":83,"line":270},[81,456,457],{"class":87},"\u002F>\n",[61,459,461],{"id":460},"hand-it-the-prefetching","Hand it the prefetching",[57,463,464],{},"This is the step that makes a difference, and it has no equivalent config flag.",[57,466,467,468,471],{},"Next prefetches every ",[78,469,470],{},"\u003CLink>"," that enters the viewport, so a page of thirty links fetches\nthirty RSC payloads and there is nothing left to narrow. There is no global switch, so swap the\nimport:",[70,473,475],{"className":191,"code":474,"language":194,"meta":76,"style":76},"import { PrecogLink as Link } from \"next-precog\";\n",[78,476,477],{"__ignoreMap":76},[81,478,479,481,484,487,490,492,494],{"class":83,"line":84},[81,480,131],{"class":91},[81,482,483],{"class":87}," { PrecogLink ",[81,485,486],{"class":91},"as",[81,488,489],{"class":87}," Link } ",[81,491,137],{"class":91},[81,493,208],{"class":95},[81,495,143],{"class":87},[57,497,498,501,502,505,506,509,510,513],{},[78,499,500],{},"PrecogLink"," is ",[78,503,504],{},"next\u002Flink"," with ",[78,507,508],{},"prefetch={false}",", which leaves precog to choose and still\nlets Next prefetch on hover. Pass ",[78,511,512],{},"prefetch"," explicitly to opt one link back in.",[57,515,516],{},"Without this the overlay still works and speculation rules still apply, but the in-app win is\ngone: everything was already warm.",[61,518,520],{"id":519},"what-it-warms","What it warms",[57,522,523,526],{},[78,524,525],{},"router.prefetch()"," for the routes the model picked, which fetches the route's RSC payload and\nits chunks. The payload only exists for routes Next renders ahead of time, so a statically\ngenerated section gains the most and a fully dynamic one gains least.",[61,528,530],{"id":529},"reading-the-state","Reading the state",[70,532,534],{"className":191,"code":533,"language":194,"meta":76,"style":76},"\"use client\";\nimport { usePrecog } from \"next-precog\";\n\nconst { enabled, pause, resume, refresh, metrics, plan } = usePrecog();\n",[78,535,536,543,556,560],{"__ignoreMap":76},[81,537,538,541],{"class":83,"line":84},[81,539,540],{"class":95},"\"use client\"",[81,542,143],{"class":87},[81,544,545,547,550,552,554],{"class":83,"line":146},[81,546,131],{"class":91},[81,548,549],{"class":87}," { usePrecog } ",[81,551,137],{"class":91},[81,553,208],{"class":95},[81,555,143],{"class":87},[81,557,558],{"class":83,"line":153},[81,559,150],{"emptyLinePlaceholder":149},[81,561,562,565,567,570,573,576,578,581,583,586,588,591,593,596,599,601,604],{"class":83,"line":261},[81,563,564],{"class":91},"const",[81,566,243],{"class":87},[81,568,569],{"class":162},"enabled",[81,571,572],{"class":87},", ",[81,574,575],{"class":162},"pause",[81,577,572],{"class":87},[81,579,580],{"class":162},"resume",[81,582,572],{"class":87},[81,584,585],{"class":162},"refresh",[81,587,572],{"class":87},[81,589,590],{"class":162},"metrics",[81,592,572],{"class":87},[81,594,595],{"class":162},"plan",[81,597,598],{"class":87}," } ",[81,600,92],{"class":91},[81,602,603],{"class":169}," usePrecog",[81,605,173],{"class":87},[61,607,609],{"id":608},"not-there-yet","Not there yet",[611,612,613,617],"ul",{},[614,615,616],"li",{},"No DevTools panel. The Nuxt adapter has one; React DevTools has no equivalent hook for it.",[614,618,619,620,623],{},"No published benchmark. ",[101,621,622],{"href":44},"The numbers"," were measured on the Nuxt\nplayground, and the two effectors are the same, but nobody has run the harness against Next.\nDo not assume they transfer exactly.",[625,626,627],"style",{},"html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .so5gQ, html code.shiki .so5gQ{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .sfrk1, html code.shiki .sfrk1{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .shcOC, html code.shiki .shcOC{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .sQHwn, html code.shiki .sQHwn{--shiki-light:#E36209;--shiki-default:#FFAB70;--shiki-dark:#FFAB70}html pre.shiki code .sByVh, html code.shiki .sByVh{--shiki-light:#22863A;--shiki-default:#85E89D;--shiki-dark:#85E89D}",{"title":76,"searchDepth":146,"depth":146,"links":629},[630,631,632,633,634,635,636],{"id":63,"depth":146,"text":64},{"id":114,"depth":146,"text":115},{"id":187,"depth":146,"text":188},{"id":460,"depth":146,"text":461},{"id":519,"depth":146,"text":520},{"id":529,"depth":146,"text":530},{"id":608,"depth":146,"text":609},"next-precog is a route handler plus a provider, for the App Router.","md",{"icon":21},{"title":18,"icon":21},{"title":18,"description":637},"5PveKKvii9tMW7u2qOcYoYdsrteYFpUX4d6ipvlznuk",[644,646],{"title":13,"path":14,"stem":15,"description":645,"icon":16,"children":-1},"nuxt-precog is a Nuxt module. Add it, set a key, and press Shift+P.",{"title":23,"path":24,"stem":25,"description":647,"icon":26,"children":-1},"From a page full of links to two or three warmed navigations, and what happens at each step.",1789942050300]