[{"data":1,"prerenderedAt":827},["ShallowReactive",2],{"navigation":3,"-guide-privacy":48,"-guide-privacy-surround":822},[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":38,"body":50,"description":71,"extension":817,"meta":818,"navigation":819,"path":39,"seo":820,"stem":40,"__hash__":821},"content\u002F1.guide\u002F7.privacy.md",{"type":51,"value":52,"toc":809,"icon":41},"minimark",[53,57,62,65,477,481,526,530,652,655,712,723,727,730,751,755,766,770,781,805],[54,55,56],"p",{},"The module sends page context and part of a visitor's browsing path to a third party\n(TypeSafe) on a schedule you control. Read this before turning it on for real traffic.",[58,59,61],"h2",{"id":60},"what-leaves-your-server","What leaves your server",[54,63,64],{},"Exactly this, and nothing else:",[66,67,72],"pre",{"className":68,"code":69,"language":70,"meta":71,"style":71},"language-jsonc shiki shiki-themes github-light github-dark github-dark","{\n  \"page\": { \"path\": \"\u002Fdocs\", \"title\": \"Docs\", \"h1\": \"Docs\", \"description\": \"...\" },\n  \"session\": {\n    \"previousPaths\": [\"\u002F\", \"\u002Fblog\"], \u002F\u002F last five, paths only\n    \"timeOnPageMs\": 4200,\n    \"scrollDepth\": 0.45, \u002F\u002F 0 to 1\n    \"scrollVelocity\": 1.2, \u002F\u002F viewport heights per second\n  },\n  \"pointer\": {\n    \"hasHover\": true,\n    \"x\": 5,\n    \"y\": 7, \u002F\u002F tenths of the viewport, not pixels\n    \"vx\": 1.2,\n    \"vy\": -0.4,\n    \"nearestIds\": [\"l2\", \"l0\", \"l5\"],\n    \"hoveredId\": \"l2\",\n  },\n  \"device\": { \"saveData\": false, \"effectiveType\": \"4g\" },\n  \"candidates\": [\n    {\n      \"id\": \"l0\",\n      \"path\": \"\u002Fdocs\u002Foptions\",\n      \"text\": \"Options\",\n      \"inViewport\": true,\n      \"position\": { \"x\": 2, \"y\": 3 },\n    },\n  ],\n}\n","jsonc","",[73,74,75,84,137,146,170,184,200,216,222,230,243,256,272,284,297,321,333,338,366,375,381,393,406,419,431,459,465,471],"code",{"__ignoreMap":71},[76,77,80],"span",{"class":78,"line":79},"line",1,[76,81,83],{"class":82},"slsVL","{\n",[76,85,87,91,94,97,100,104,107,110,112,115,117,120,122,124,126,129,131,134],{"class":78,"line":86},2,[76,88,90],{"class":89},"suiK_","  \"page\"",[76,92,93],{"class":82},": { ",[76,95,96],{"class":89},"\"path\"",[76,98,99],{"class":82},": ",[76,101,103],{"class":102},"sfrk1","\"\u002Fdocs\"",[76,105,106],{"class":82},", ",[76,108,109],{"class":89},"\"title\"",[76,111,99],{"class":82},[76,113,114],{"class":102},"\"Docs\"",[76,116,106],{"class":82},[76,118,119],{"class":89},"\"h1\"",[76,121,99],{"class":82},[76,123,114],{"class":102},[76,125,106],{"class":82},[76,127,128],{"class":89},"\"description\"",[76,130,99],{"class":82},[76,132,133],{"class":102},"\"...\"",[76,135,136],{"class":82}," },\n",[76,138,140,143],{"class":78,"line":139},3,[76,141,142],{"class":89},"  \"session\"",[76,144,145],{"class":82},": {\n",[76,147,149,152,155,158,160,163,166],{"class":78,"line":148},4,[76,150,151],{"class":89},"    \"previousPaths\"",[76,153,154],{"class":82},": [",[76,156,157],{"class":102},"\"\u002F\"",[76,159,106],{"class":82},[76,161,162],{"class":102},"\"\u002Fblog\"",[76,164,165],{"class":82},"], ",[76,167,169],{"class":168},"sCsY4","\u002F\u002F last five, paths only\n",[76,171,173,176,178,181],{"class":78,"line":172},5,[76,174,175],{"class":89},"    \"timeOnPageMs\"",[76,177,99],{"class":82},[76,179,180],{"class":89},"4200",[76,182,183],{"class":82},",\n",[76,185,187,190,192,195,197],{"class":78,"line":186},6,[76,188,189],{"class":89},"    \"scrollDepth\"",[76,191,99],{"class":82},[76,193,194],{"class":89},"0.45",[76,196,106],{"class":82},[76,198,199],{"class":168},"\u002F\u002F 0 to 1\n",[76,201,203,206,208,211,213],{"class":78,"line":202},7,[76,204,205],{"class":89},"    \"scrollVelocity\"",[76,207,99],{"class":82},[76,209,210],{"class":89},"1.2",[76,212,106],{"class":82},[76,214,215],{"class":168},"\u002F\u002F viewport heights per second\n",[76,217,219],{"class":78,"line":218},8,[76,220,221],{"class":82},"  },\n",[76,223,225,228],{"class":78,"line":224},9,[76,226,227],{"class":89},"  \"pointer\"",[76,229,145],{"class":82},[76,231,233,236,238,241],{"class":78,"line":232},10,[76,234,235],{"class":89},"    \"hasHover\"",[76,237,99],{"class":82},[76,239,240],{"class":89},"true",[76,242,183],{"class":82},[76,244,246,249,251,254],{"class":78,"line":245},11,[76,247,248],{"class":89},"    \"x\"",[76,250,99],{"class":82},[76,252,253],{"class":89},"5",[76,255,183],{"class":82},[76,257,259,262,264,267,269],{"class":78,"line":258},12,[76,260,261],{"class":89},"    \"y\"",[76,263,99],{"class":82},[76,265,266],{"class":89},"7",[76,268,106],{"class":82},[76,270,271],{"class":168},"\u002F\u002F tenths of the viewport, not pixels\n",[76,273,275,278,280,282],{"class":78,"line":274},13,[76,276,277],{"class":89},"    \"vx\"",[76,279,99],{"class":82},[76,281,210],{"class":89},[76,283,183],{"class":82},[76,285,287,290,292,295],{"class":78,"line":286},14,[76,288,289],{"class":89},"    \"vy\"",[76,291,99],{"class":82},[76,293,294],{"class":89},"-0.4",[76,296,183],{"class":82},[76,298,300,303,305,308,310,313,315,318],{"class":78,"line":299},15,[76,301,302],{"class":89},"    \"nearestIds\"",[76,304,154],{"class":82},[76,306,307],{"class":102},"\"l2\"",[76,309,106],{"class":82},[76,311,312],{"class":102},"\"l0\"",[76,314,106],{"class":82},[76,316,317],{"class":102},"\"l5\"",[76,319,320],{"class":82},"],\n",[76,322,324,327,329,331],{"class":78,"line":323},16,[76,325,326],{"class":89},"    \"hoveredId\"",[76,328,99],{"class":82},[76,330,307],{"class":102},[76,332,183],{"class":82},[76,334,336],{"class":78,"line":335},17,[76,337,221],{"class":82},[76,339,341,344,346,349,351,354,356,359,361,364],{"class":78,"line":340},18,[76,342,343],{"class":89},"  \"device\"",[76,345,93],{"class":82},[76,347,348],{"class":89},"\"saveData\"",[76,350,99],{"class":82},[76,352,353],{"class":89},"false",[76,355,106],{"class":82},[76,357,358],{"class":89},"\"effectiveType\"",[76,360,99],{"class":82},[76,362,363],{"class":102},"\"4g\"",[76,365,136],{"class":82},[76,367,369,372],{"class":78,"line":368},19,[76,370,371],{"class":89},"  \"candidates\"",[76,373,374],{"class":82},": [\n",[76,376,378],{"class":78,"line":377},20,[76,379,380],{"class":82},"    {\n",[76,382,384,387,389,391],{"class":78,"line":383},21,[76,385,386],{"class":89},"      \"id\"",[76,388,99],{"class":82},[76,390,312],{"class":102},[76,392,183],{"class":82},[76,394,396,399,401,404],{"class":78,"line":395},22,[76,397,398],{"class":89},"      \"path\"",[76,400,99],{"class":82},[76,402,403],{"class":102},"\"\u002Fdocs\u002Foptions\"",[76,405,183],{"class":82},[76,407,409,412,414,417],{"class":78,"line":408},23,[76,410,411],{"class":89},"      \"text\"",[76,413,99],{"class":82},[76,415,416],{"class":102},"\"Options\"",[76,418,183],{"class":82},[76,420,422,425,427,429],{"class":78,"line":421},24,[76,423,424],{"class":89},"      \"inViewport\"",[76,426,99],{"class":82},[76,428,240],{"class":89},[76,430,183],{"class":82},[76,432,434,437,439,442,444,447,449,452,454,457],{"class":78,"line":433},25,[76,435,436],{"class":89},"      \"position\"",[76,438,93],{"class":82},[76,440,441],{"class":89},"\"x\"",[76,443,99],{"class":82},[76,445,446],{"class":89},"2",[76,448,106],{"class":82},[76,450,451],{"class":89},"\"y\"",[76,453,99],{"class":82},[76,455,456],{"class":89},"3",[76,458,136],{"class":82},[76,460,462],{"class":78,"line":461},26,[76,463,464],{"class":82},"    },\n",[76,466,468],{"class":78,"line":467},27,[76,469,470],{"class":82},"  ],\n",[76,472,474],{"class":78,"line":473},28,[76,475,476],{"class":82},"}\n",[58,478,480],{"id":479},"what-does-not","What does not",[482,483,484,496,506,516],"ul",{},[485,486,487,491,492,495],"li",{},[488,489,490],"strong",{},"The API key."," It lives in ",[73,493,494],{},"runtimeConfig.precog.apiKey",", which is server only. There is an\ne2e test that starts the server with a known key and fails if that string appears in any\ndocument or bundle the browser receives.",[485,497,498,501,502,505],{},[488,499,500],{},"Full URLs."," Only rooted paths, and query strings only when ",[73,503,504],{},"privacy.sendQuery"," is on.",[485,507,508,511,512,515],{},[488,509,510],{},"Any identifier."," No cookie, no user id, no device id, no fingerprint. Nothing ties two\nsessions together, and the module stores nothing beyond a counter in ",[73,513,514],{},"sessionStorage",".",[485,517,518,521,522,525],{},[488,519,520],{},"Page content."," Only the title, the first ",[73,523,524],{},"h1",", the meta description, and the text of the\ncandidate links.",[58,527,529],{"id":528},"switches","Switches",[66,531,535],{"className":532,"code":533,"language":534,"meta":71,"style":71},"language-ts shiki shiki-themes github-light github-dark github-dark","precog: {\n  privacy: {\n    sendQuery: false,       \u002F\u002F query strings, off by default because they carry tokens\n    sendAnchorText: true,   \u002F\u002F link text; turn off and Jev sees paths only\n    sendHistory: true,      \u002F\u002F the last five paths\n    requireConsent: false,  \u002F\u002F nothing runs until usePrecog().grantConsent()\n  },\n  exclude: ['\u002Flogout', '\u002Fsignout', '\u002Fapi\u002F**', '\u002Fauth\u002F**', '\u002Fcart\u002F**'],\n}\n","ts",[73,536,537,545,552,567,582,597,612,616,648],{"__ignoreMap":71},[76,538,539,543],{"class":78,"line":79},[76,540,542],{"class":541},"shcOC","precog",[76,544,145],{"class":82},[76,546,547,550],{"class":78,"line":86},[76,548,549],{"class":541},"  privacy",[76,551,145],{"class":82},[76,553,554,557,559,561,564],{"class":78,"line":139},[76,555,556],{"class":541},"    sendQuery",[76,558,99],{"class":82},[76,560,353],{"class":89},[76,562,563],{"class":82},",       ",[76,565,566],{"class":168},"\u002F\u002F query strings, off by default because they carry tokens\n",[76,568,569,572,574,576,579],{"class":78,"line":148},[76,570,571],{"class":541},"    sendAnchorText",[76,573,99],{"class":82},[76,575,240],{"class":89},[76,577,578],{"class":82},",   ",[76,580,581],{"class":168},"\u002F\u002F link text; turn off and Jev sees paths only\n",[76,583,584,587,589,591,594],{"class":78,"line":172},[76,585,586],{"class":541},"    sendHistory",[76,588,99],{"class":82},[76,590,240],{"class":89},[76,592,593],{"class":82},",      ",[76,595,596],{"class":168},"\u002F\u002F the last five paths\n",[76,598,599,602,604,606,609],{"class":78,"line":186},[76,600,601],{"class":541},"    requireConsent",[76,603,99],{"class":82},[76,605,353],{"class":89},[76,607,608],{"class":82},",  ",[76,610,611],{"class":168},"\u002F\u002F nothing runs until usePrecog().grantConsent()\n",[76,613,614],{"class":78,"line":202},[76,615,221],{"class":82},[76,617,618,621,623,626,628,631,633,636,638,641,643,646],{"class":78,"line":218},[76,619,620],{"class":541},"  exclude",[76,622,154],{"class":82},[76,624,625],{"class":102},"'\u002Flogout'",[76,627,106],{"class":82},[76,629,630],{"class":102},"'\u002Fsignout'",[76,632,106],{"class":82},[76,634,635],{"class":102},"'\u002Fapi\u002F**'",[76,637,106],{"class":82},[76,639,640],{"class":102},"'\u002Fauth\u002F**'",[76,642,106],{"class":82},[76,644,645],{"class":102},"'\u002Fcart\u002F**'",[76,647,320],{"class":82},[76,649,650],{"class":78,"line":224},[76,651,476],{"class":82},[54,653,654],{},"With a consent banner:",[66,656,658],{"className":532,"code":657,"language":534,"meta":71,"style":71},"const { grantConsent } = usePrecog();\n\nfunction onAccept() {\n  grantConsent();\n}\n",[73,659,660,684,690,701,708],{"__ignoreMap":71},[76,661,662,666,669,672,675,678,681],{"class":78,"line":79},[76,663,665],{"class":664},"so5gQ","const",[76,667,668],{"class":82}," { ",[76,670,671],{"class":89},"grantConsent",[76,673,674],{"class":82}," } ",[76,676,677],{"class":664},"=",[76,679,680],{"class":541}," usePrecog",[76,682,683],{"class":82},"();\n",[76,685,686],{"class":78,"line":86},[76,687,689],{"emptyLinePlaceholder":688},true,"\n",[76,691,692,695,698],{"class":78,"line":139},[76,693,694],{"class":664},"function",[76,696,697],{"class":541}," onAccept",[76,699,700],{"class":82},"() {\n",[76,702,703,706],{"class":78,"line":148},[76,704,705],{"class":541},"  grantConsent",[76,707,683],{"class":82},[76,709,710],{"class":78,"line":172},[76,711,476],{"class":82},[54,713,714,715,718,719,722],{},"With ",[73,716,717],{},"requireConsent: true"," the client collects nothing, sends nothing and writes no rules\nuntil ",[73,720,721],{},"grantConsent()"," is called. It is not a delay; it is a hard stop.",[58,724,726],{"id":725},"untrusted-link-text","Untrusted link text",[54,728,729],{},"Anchor text is page content, and on many sites page content comes from users. It is sent as\nthe description of a choice option, so the worst it can do is argue for its own option. Three\nthings keep that contained:",[731,732,734,738,741],"steps",{"level":733},"4",[735,736,737],"h4",{},"The server strips backticks and newlines and truncates to 80 characters.",[735,739,740],{},"The model can only answer with ids the server put in the request.",[735,742,743,744,106,747,750],{},"The server drops any id that was not in its own request, and the ids must be the exact\ndense sequence ",[73,745,746],{},"l0",[73,748,749],{},"l1",", ... A test covers this.",[58,752,754],{"id":753},"prediction-responses-are-never-shared","Prediction responses are never shared",[54,756,757,758,761,762,765],{},"The endpoint sends ",[73,759,760],{},"Cache-Control: no-store",". The server-side cache is keyed on the page and\nits link set plus coarse signal buckets, never on anything identifying, and it holds only\n",[73,763,764],{},"{ id, probability }"," pairs.",[58,767,769],{"id":768},"speculative-loads-reach-your-own-server","Speculative loads reach your own server",[54,771,772,773,776,777,780],{},"A prefetch or prerender is a real request for a real page, with the visitor's cookies, carrying\n",[73,774,775],{},"Sec-Purpose: prefetch"," (or ",[73,778,779],{},"prefetch;prerender","). Two consequences:",[482,782,783,794],{},[485,784,785,786,789,790,793],{},"Analytics will see page views that never happened. Gate them on ",[73,787,788],{},"document.prerendering"," and\nthe ",[73,791,792],{},"prerenderingchange"," event.",[485,795,796,797,800,801,804],{},"Anything with a side effect on ",[73,798,799],{},"GET"," must be on ",[73,802,803],{},"exclude",". The defaults cover the usual\nsuspects; your own are your own.",[806,807,808],"style",{},"html pre.shiki code .shcOC, html code.shiki .shcOC{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}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 .so5gQ, html code.shiki .so5gQ{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#F97583}",{"title":71,"searchDepth":86,"depth":86,"links":810},[811,812,813,814,815,816],{"id":60,"depth":86,"text":61},{"id":479,"depth":86,"text":480},{"id":528,"depth":86,"text":529},{"id":725,"depth":86,"text":726},{"id":753,"depth":86,"text":754},{"id":768,"depth":86,"text":769},"md",{"icon":41},{"icon":41},{"title":38,"description":71},"R5p9h60BeAqbk4RB57gZ7am9k7sMQ_RFdQNVurz9_o0",[823,825],{"title":33,"path":34,"stem":35,"description":824,"icon":36,"children":-1},"The composable, the hooks, and the page and link attributes.",{"title":43,"path":44,"stem":45,"description":826,"icon":46,"children":-1},"Eight scripted sessions per arm, six navigations each, real Chrome against a production\nbuild, throttled to 250 ms of latency and 2000 kbit\u002Fs, predictions from Jev.",1789942050301]