[{"data":1,"prerenderedAt":993},["ShallowReactive",2],{"navigation_docs":3,"-nuxthub-overview":171,"-nuxthub-overview-surround":988},[4,30,55,105,122,136],{"title":5,"path":6,"stem":7,"children":8,"page":29},"Getting Started","/getting-started","1.getting-started",[9,14,19,24],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","/getting-started/introduction","1.getting-started/1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Installation","/getting-started/installation","1.getting-started/2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"Quick Start","/getting-started/quick-start","1.getting-started/3.quick-start","i-lucide-zap",{"title":25,"path":26,"stem":27,"icon":28},"Agent Skills","/getting-started/agent-skills","1.getting-started/4.agent-skills","i-lucide-sparkles",false,{"title":31,"path":32,"stem":33,"children":34,"page":29},"Core Concepts","/core-concepts","2.core-concepts",[35,40,45,50],{"title":36,"path":37,"stem":38,"icon":39},"Wide Events","/core-concepts/wide-events","2.core-concepts/1.wide-events","i-lucide-layers",{"title":41,"path":42,"stem":43,"icon":44},"Structured Errors","/core-concepts/structured-errors","2.core-concepts/2.structured-errors","i-lucide-shield-alert",{"title":46,"path":47,"stem":48,"icon":49},"Best Practices","/core-concepts/best-practices","2.core-concepts/3.best-practices","i-lucide-shield-check",{"title":51,"path":52,"stem":53,"icon":54},"Typed Fields","/core-concepts/typed-fields","2.core-concepts/4.typed-fields","i-simple-icons-typescript",{"title":56,"path":57,"stem":58,"children":59,"page":29},"Adapters","/adapters","3.adapters",[60,65,70,75,80,85,90,95,100],{"title":61,"path":62,"stem":63,"icon":64},"Overview","/adapters/overview","3.adapters/1.overview","i-custom-plug",{"title":66,"path":67,"stem":68,"icon":69},"Axiom","/adapters/axiom","3.adapters/2.axiom","i-custom-axiom",{"title":71,"path":72,"stem":73,"icon":74},"OTLP","/adapters/otlp","3.adapters/3.otlp","i-simple-icons-opentelemetry",{"title":76,"path":77,"stem":78,"icon":79},"PostHog","/adapters/posthog","3.adapters/4.posthog","i-simple-icons-posthog",{"title":81,"path":82,"stem":83,"icon":84},"Sentry","/adapters/sentry","3.adapters/5.sentry","i-simple-icons-sentry",{"title":86,"path":87,"stem":88,"icon":89},"Better Stack","/adapters/better-stack","3.adapters/6.better-stack","i-simple-icons-betterstack",{"title":91,"path":92,"stem":93,"icon":94},"Custom Adapters","/adapters/custom","3.adapters/7.custom","i-lucide-code",{"title":96,"path":97,"stem":98,"icon":99},"Pipeline","/adapters/pipeline","3.adapters/8.pipeline","i-lucide-workflow",{"title":101,"path":102,"stem":103,"icon":104},"Browser","/adapters/browser","3.adapters/9.browser","i-lucide-globe",{"title":106,"path":107,"stem":108,"children":109,"page":29},"Enrichers","/enrichers","4.enrichers",[110,113,118],{"title":61,"path":111,"stem":112,"icon":28},"/enrichers/overview","4.enrichers/1.overview",{"title":114,"path":115,"stem":116,"icon":117},"Built-in","/enrichers/built-in","4.enrichers/2.built-in","i-lucide-puzzle",{"title":119,"path":120,"stem":121,"icon":94},"Custom","/enrichers/custom","4.enrichers/3.custom",{"title":123,"path":124,"stem":125,"children":126,"page":29},"NuxtHub","/nuxthub","5.nuxthub",[127,131],{"title":61,"path":128,"stem":129,"icon":130},"/nuxthub/overview","5.nuxthub/1.overview","i-lucide-database",{"title":132,"path":133,"stem":134,"icon":135},"Retention","/nuxthub/retention","5.nuxthub/2.retention","i-lucide-clock",{"title":137,"path":138,"stem":139,"children":140,"page":29},"Examples","/examples","6.examples",[141,146,151,156,161,166],{"title":142,"path":143,"stem":144,"icon":145},"Next.js","/examples/nextjs","6.examples/1.nextjs","i-simple-icons-nextdotjs",{"title":147,"path":148,"stem":149,"icon":150},"TanStack Start","/examples/tanstack-start","6.examples/2.tanstack-start","i-custom-tanstack",{"title":152,"path":153,"stem":154,"icon":155},"Hono","/examples/hono","6.examples/3.hono","i-simple-icons-hono",{"title":157,"path":158,"stem":159,"icon":160},"Express","/examples/express","6.examples/4.express","i-simple-icons-express",{"title":162,"path":163,"stem":164,"icon":165},"Elysia","/examples/elysia","6.examples/5.elysia","i-custom-elysia",{"title":167,"path":168,"stem":169,"icon":170},"Fastify","/examples/fastify","6.examples/6.fastify","i-simple-icons-fastify",{"id":172,"title":173,"body":174,"description":975,"extension":976,"links":977,"meta":984,"navigation":985,"path":128,"seo":986,"stem":129,"__hash__":987},"docs/5.nuxthub/1.overview.md","NuxtHub Storage",{"type":175,"value":176,"toc":964},"minimark",[177,185,190,193,222,227,231,311,318,340,344,350,464,477,480,510,528,532,540,550,555,565,784,801,805,808,826,833,837,845,948,952,960],[178,179,180,184],"p",{},[181,182,183],"code",{},"@evlog/nuxthub"," stores your evlog wide events directly in your NuxtHub database. No external logging service needed — your logs live next to your data, with automatic cleanup based on a retention policy.",[186,187,189],"h2",{"id":188},"why-self-hosted-logs","Why Self-Hosted Logs?",[178,191,192],{},"External logging services (Axiom, Datadog, etc.) are great for production at scale. But sometimes you want:",[194,195,196,204,210,216],"ul",{},[197,198,199,203],"li",{},[200,201,202],"strong",{},"Zero external dependencies"," — logs stored in the same database as your app",[197,205,206,209],{},[200,207,208],{},"Full data ownership"," — no third-party access to your log data",[197,211,212,215],{},[200,213,214],{},"Free tier friendly"," — no per-event pricing, just your existing database",[197,217,218,221],{},[200,219,220],{},"Development & staging"," — full log visibility without paying for a service",[178,223,224,226],{},[181,225,183],{}," works as a drop-in drain. Your existing evlog setup stays the same — you just get a database-backed storage layer on top.",[186,228,230],{"id":229},"install","Install",[232,233,234,262,279,295],"code-group",{},[235,236,242],"pre",{"className":237,"code":238,"filename":239,"language":240,"meta":241,"style":241},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @nuxthub/core @evlog/nuxthub\n","pnpm","bash","",[181,243,244],{"__ignoreMap":241},[245,246,249,252,256,259],"span",{"class":247,"line":248},"line",1,[245,250,239],{"class":251},"sBMFI",[245,253,255],{"class":254},"sfazB"," add",[245,257,258],{"class":254}," @nuxthub/core",[245,260,261],{"class":254}," @evlog/nuxthub\n",[235,263,266],{"className":237,"code":264,"filename":265,"language":240,"meta":241,"style":241},"npm install @nuxthub/core @evlog/nuxthub\n","npm",[181,267,268],{"__ignoreMap":241},[245,269,270,272,275,277],{"class":247,"line":248},[245,271,265],{"class":251},[245,273,274],{"class":254}," install",[245,276,258],{"class":254},[245,278,261],{"class":254},[235,280,283],{"className":237,"code":281,"filename":282,"language":240,"meta":241,"style":241},"yarn add @nuxthub/core @evlog/nuxthub\n","yarn",[181,284,285],{"__ignoreMap":241},[245,286,287,289,291,293],{"class":247,"line":248},[245,288,282],{"class":251},[245,290,255],{"class":254},[245,292,258],{"class":254},[245,294,261],{"class":254},[235,296,299],{"className":237,"code":297,"filename":298,"language":240,"meta":241,"style":241},"bun add @nuxthub/core @evlog/nuxthub\n","bun",[181,300,301],{"__ignoreMap":241},[245,302,303,305,307,309],{"class":247,"line":248},[245,304,298],{"class":251},[245,306,255],{"class":254},[245,308,258],{"class":254},[245,310,261],{"class":254},[178,312,313,314,317],{},"Or with ",[181,315,316],{},"nuxi",":",[235,319,321],{"className":237,"code":320,"language":240,"meta":241,"style":241},"npx nuxi module add @nuxthub/core @evlog/nuxthub\n",[181,322,323],{"__ignoreMap":241},[245,324,325,328,331,334,336,338],{"class":247,"line":248},[245,326,327],{"class":251},"npx",[245,329,330],{"class":254}," nuxi",[245,332,333],{"class":254}," module",[245,335,255],{"class":254},[245,337,258],{"class":254},[245,339,261],{"class":254},[186,341,343],{"id":342},"setup","Setup",[178,345,346,347,317],{},"Add the module to your ",[181,348,349],{},"nuxt.config.ts",[235,351,355],{"className":352,"code":353,"filename":349,"language":354,"meta":241,"style":241},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  modules: ['@nuxthub/core', '@evlog/nuxthub'],\n\n  evlog: {\n    retention: '7d',\n  },\n})\n","typescript",[181,356,357,378,414,421,432,449,455],{"__ignoreMap":241},[245,358,359,363,366,370,374],{"class":247,"line":248},[245,360,362],{"class":361},"s7zQu","export",[245,364,365],{"class":361}," default",[245,367,369],{"class":368},"s2Zo4"," defineNuxtConfig",[245,371,373],{"class":372},"sTEyZ","(",[245,375,377],{"class":376},"sMK4o","{\n",[245,379,381,385,387,390,393,396,398,401,404,406,408,411],{"class":247,"line":380},2,[245,382,384],{"class":383},"swJcz","  modules",[245,386,317],{"class":376},[245,388,389],{"class":372}," [",[245,391,392],{"class":376},"'",[245,394,395],{"class":254},"@nuxthub/core",[245,397,392],{"class":376},[245,399,400],{"class":376},",",[245,402,403],{"class":376}," '",[245,405,183],{"class":254},[245,407,392],{"class":376},[245,409,410],{"class":372},"]",[245,412,413],{"class":376},",\n",[245,415,417],{"class":247,"line":416},3,[245,418,420],{"emptyLinePlaceholder":419},true,"\n",[245,422,424,427,429],{"class":247,"line":423},4,[245,425,426],{"class":383},"  evlog",[245,428,317],{"class":376},[245,430,431],{"class":376}," {\n",[245,433,435,438,440,442,445,447],{"class":247,"line":434},5,[245,436,437],{"class":383},"    retention",[245,439,317],{"class":376},[245,441,403],{"class":376},[245,443,444],{"class":254},"7d",[245,446,392],{"class":376},[245,448,413],{"class":376},[245,450,452],{"class":247,"line":451},6,[245,453,454],{"class":376},"  },\n",[245,456,458,461],{"class":247,"line":457},7,[245,459,460],{"class":376},"}",[245,462,463],{"class":372},")\n",[178,465,466,467,469,470,472,473,476],{},"Even if ",[181,468,183],{}," can auto-register missing modules, we recommend explicitly installing ",[181,471,395],{}," and registering it in ",[181,474,475],{},"modules"," for a clearer and more predictable setup.",[178,478,479],{},"That's it. The module automatically:",[481,482,483,493,500,507],"ol",{},[197,484,485,486,489,490,492],{},"Installs ",[181,487,488],{},"evlog/nuxt"," and ",[181,491,395],{}," if not already registered",[197,494,495,496,499],{},"Registers the ",[181,497,498],{},"evlog_events"," database schema with NuxtHub",[197,501,502,503,506],{},"Hooks into ",[181,504,505],{},"evlog:drain"," to store every event in the database",[197,508,509],{},"Schedules a cleanup task based on your retention policy",[511,512,514,517,518,524,525,527],"callout",{"color":513,"icon":13},"info",[200,515,516],{},"Prerequisites:"," Your project must use ",[519,520,123],"a",{"href":521,"rel":522},"https://hub.nuxt.com",[523],"nofollow"," with a database configured. ",[181,526,183],{}," uses Drizzle ORM to interact with the database.",[186,529,531],{"id":530},"how-it-works","How It Works",[235,533,538],{"className":534,"code":536,"language":537},[535],"language-text","Request → evlog wide event → evlog:drain hook → INSERT into evlog_events table\n                                                          ↓\n                          Cron task (automatic) → DELETE events older than retention\n","text",[181,539,536],{"__ignoreMap":241},[178,541,542,543,545,546,549],{},"Every wide event emitted by evlog is stored as a row in the ",[181,544,498],{}," table. The drain plugin handles both single events and batches (when used with the ",[519,547,548],{"href":97},"pipeline",").",[551,552,554],"h3",{"id":553},"database-schema","Database Schema",[178,556,557,558,560,561,564],{},"The ",[181,559,498],{}," table stores indexed columns for fast querying and a ",[181,562,563],{},"data"," JSON column for all remaining fields:",[566,567,568,584],"table",{},[569,570,571],"thead",{},[572,573,574,578,581],"tr",{},[575,576,577],"th",{},"Column",[575,579,580],{},"Type",[575,582,583],{},"Description",[585,586,587,602,616,630,644,658,672,686,701,715,729,743,757,770],"tbody",{},[572,588,589,595,599],{},[590,591,592],"td",{},[181,593,594],{},"id",[590,596,597],{},[181,598,537],{},[590,600,601],{},"UUID primary key",[572,603,604,609,613],{},[590,605,606],{},[181,607,608],{},"timestamp",[590,610,611],{},[181,612,537],{},[590,614,615],{},"Event timestamp",[572,617,618,623,627],{},[590,619,620],{},[181,621,622],{},"level",[590,624,625],{},[181,626,537],{},[590,628,629],{},"Log level (info, warn, error, debug)",[572,631,632,637,641],{},[590,633,634],{},[181,635,636],{},"service",[590,638,639],{},[181,640,537],{},[590,642,643],{},"Service name",[572,645,646,651,655],{},[590,647,648],{},[181,649,650],{},"environment",[590,652,653],{},[181,654,537],{},[590,656,657],{},"Environment (production, staging, etc.)",[572,659,660,665,669],{},[590,661,662],{},[181,663,664],{},"method",[590,666,667],{},[181,668,537],{},[590,670,671],{},"HTTP method",[572,673,674,679,683],{},[590,675,676],{},[181,677,678],{},"path",[590,680,681],{},[181,682,537],{},[590,684,685],{},"Request path",[572,687,688,693,698],{},[590,689,690],{},[181,691,692],{},"status",[590,694,695],{},[181,696,697],{},"integer",[590,699,700],{},"HTTP status code",[572,702,703,708,712],{},[590,704,705],{},[181,706,707],{},"duration_ms",[590,709,710],{},[181,711,697],{},[590,713,714],{},"Request duration in milliseconds",[572,716,717,722,726],{},[590,718,719],{},[181,720,721],{},"request_id",[590,723,724],{},[181,725,537],{},[590,727,728],{},"Request correlation ID",[572,730,731,736,740],{},[590,732,733],{},[181,734,735],{},"source",[590,737,738],{},[181,739,537],{},[590,741,742],{},"Event source (server, client)",[572,744,745,750,754],{},[590,746,747],{},[181,748,749],{},"error",[590,751,752],{},[181,753,537],{},[590,755,756],{},"Error details (JSON string)",[572,758,759,763,767],{},[590,760,761],{},[181,762,563],{},[590,764,765],{},[181,766,537],{},[590,768,769],{},"All remaining event fields (JSON)",[572,771,772,777,781],{},[590,773,774],{},[181,775,776],{},"created_at",[590,778,779],{},[181,780,537],{},[590,782,783],{},"Row insertion timestamp",[178,785,786,787,789,790,789,792,789,794,789,796,789,798,800],{},"Indexed columns: ",[181,788,608],{},", ",[181,791,622],{},[181,793,636],{},[181,795,692],{},[181,797,721],{},[181,799,776],{},".",[551,802,804],{"id":803},"dialect-support","Dialect Support",[178,806,807],{},"The schema is automatically registered for your NuxtHub database dialect:",[194,809,810,816,821],{},[197,811,812,815],{},[200,813,814],{},"SQLite"," (default for Cloudflare D1)",[197,817,818],{},[200,819,820],{},"MySQL",[197,822,823],{},[200,824,825],{},"PostgreSQL",[178,827,828,829,832],{},"The correct schema is selected via the ",[181,830,831],{},"hub:db:schema:extend"," hook based on your NuxtHub configuration.",[186,834,836],{"id":835},"combining-with-external-adapters","Combining with External Adapters",[178,838,839,841,842,844],{},[181,840,183],{}," doesn't replace external adapters — you can use both. The module registers its own ",[181,843,505],{}," hook, so any other drain plugins you have will still work:",[235,846,849],{"className":352,"code":847,"filename":848,"language":354,"meta":241,"style":241},"import { createAxiomDrain } from 'evlog/axiom'\n\nexport default defineNitroPlugin((nitroApp) => {\n  // This runs alongside @evlog/nuxthub's built-in drain\n  nitroApp.hooks.hook('evlog:drain', createAxiomDrain())\n})\n","server/plugins/evlog-drain.ts",[181,850,851,876,880,906,912,942],{"__ignoreMap":241},[245,852,853,856,859,862,865,868,870,873],{"class":247,"line":248},[245,854,855],{"class":361},"import",[245,857,858],{"class":376}," {",[245,860,861],{"class":372}," createAxiomDrain",[245,863,864],{"class":376}," }",[245,866,867],{"class":361}," from",[245,869,403],{"class":376},[245,871,872],{"class":254},"evlog/axiom",[245,874,875],{"class":376},"'\n",[245,877,878],{"class":247,"line":380},[245,879,420],{"emptyLinePlaceholder":419},[245,881,882,884,886,889,891,893,897,900,904],{"class":247,"line":416},[245,883,362],{"class":361},[245,885,365],{"class":361},[245,887,888],{"class":368}," defineNitroPlugin",[245,890,373],{"class":372},[245,892,373],{"class":376},[245,894,896],{"class":895},"sHdIc","nitroApp",[245,898,899],{"class":376},")",[245,901,903],{"class":902},"spNyl"," =>",[245,905,431],{"class":376},[245,907,908],{"class":247,"line":423},[245,909,911],{"class":910},"sHwdD","  // This runs alongside @evlog/nuxthub's built-in drain\n",[245,913,914,917,919,922,924,927,929,931,933,935,937,939],{"class":247,"line":434},[245,915,916],{"class":372},"  nitroApp",[245,918,800],{"class":376},[245,920,921],{"class":372},"hooks",[245,923,800],{"class":376},[245,925,926],{"class":368},"hook",[245,928,373],{"class":383},[245,930,392],{"class":376},[245,932,505],{"class":254},[245,934,392],{"class":376},[245,936,400],{"class":376},[245,938,861],{"class":368},[245,940,941],{"class":383},"())\n",[245,943,944,946],{"class":247,"line":451},[245,945,460],{"class":376},[245,947,463],{"class":372},[186,949,951],{"id":950},"next-steps","Next Steps",[194,953,954],{},[197,955,956,959],{},[519,957,958],{"href":133},"Retention & Cleanup"," — Configure retention policy and cleanup scheduling",[961,962,963],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":241,"searchDepth":380,"depth":380,"links":965},[966,967,968,969,973,974],{"id":188,"depth":380,"text":189},{"id":229,"depth":380,"text":230},{"id":342,"depth":380,"text":343},{"id":530,"depth":380,"text":531,"children":970},[971,972],{"id":553,"depth":416,"text":554},{"id":803,"depth":416,"text":804},{"id":835,"depth":380,"text":836},{"id":950,"depth":380,"text":951},"Self-hosted log retention for evlog using NuxtHub database storage. Store, query, and automatically clean up your structured logs with zero external dependencies.","md",[978,983],{"label":123,"icon":979,"to":521,"target":980,"color":981,"variant":982},"i-lucide-external-link","_blank","neutral","subtle",{"label":56,"icon":64,"to":62,"color":981,"variant":982},{},{"title":61,"icon":130},{"title":173,"description":975},"F5e3TvYQeqA50ikCUEtSClNVaxTBoTDzLW2Svq_BEQs",[989,991],{"title":119,"path":120,"stem":121,"description":990,"icon":94,"children":-1},"Write custom enrichers to add derived context to your wide events. Add deployment metadata, tenant IDs, feature flags, or any computed data.",{"title":132,"path":133,"stem":134,"description":992,"icon":135,"children":-1},"Configure how long logs are kept in NuxtHub and how they are automatically cleaned up with scheduled tasks, cron jobs, and retention policies.",1772883108541]