[{"data":1,"prerenderedAt":1956},["ShallowReactive",2],{"navigation":3,"-examples-validate-data":184,"-examples-validate-data-surround":1952},[4,91,133,161,168],{"title":5,"path":6,"stem":7,"children":8,"icon":90},"Guide","/guide","1.guide/0.index",[9,12,53,69],{"title":10,"path":6,"stem":7,"icon":11},"Getting Started","pixel:play",{"title":5,"icon":13,"path":14,"stem":15,"children":16,"page":52},"ph:book-open-duotone","/guide/basics","1.guide/1.basics",[17,22,27,32,37,42,47],{"title":18,"path":19,"stem":20,"icon":21},"Request Lifecycle","/guide/basics/lifecycle","1.guide/1.basics/1.lifecycle","icon-park-outline:handle-round",{"title":23,"path":24,"stem":25,"icon":26},"Routing","/guide/basics/routing","1.guide/1.basics/2.routing","solar:routing-bold",{"title":28,"path":29,"stem":30,"icon":31},"Middleware","/guide/basics/middleware","1.guide/1.basics/3.middleware","mdi:middleware-outline",{"title":33,"path":34,"stem":35,"icon":36},"Event Handlers","/guide/basics/handler","1.guide/1.basics/4.handler","mdi:function",{"title":38,"path":39,"stem":40,"icon":41},"Sending Response","/guide/basics/response","1.guide/1.basics/5.response","tabler:json",{"title":43,"path":44,"stem":45,"icon":46},"Error Handling","/guide/basics/error","1.guide/1.basics/6.error","tabler:error-404",{"title":48,"path":49,"stem":50,"icon":51},"Nested Apps","/guide/basics/nested-apps","1.guide/1.basics/7.nested-apps","material-symbols-light:layers-outline",false,{"title":54,"icon":55,"path":56,"stem":57,"children":58,"page":52},"API","material-symbols-light:api-rounded","/guide/api","1.guide/900.api",[59,64],{"title":60,"path":61,"stem":62,"icon":63},"H3","/guide/api/h3","1.guide/900.api/1.h3","material-symbols:bolt-rounded",{"title":65,"path":66,"stem":67,"icon":68},"H3Event","/guide/api/h3event","1.guide/900.api/2.h3event","material-symbols:data-object-rounded",{"title":70,"icon":71,"path":72,"stem":73,"children":74,"page":52},"Advanced","hugeicons:more-01","/guide/advanced","1.guide/901.advanced",[75,80,85],{"title":76,"path":77,"stem":78,"icon":79},"Plugins","/guide/advanced/plugins","1.guide/901.advanced/1.plugins","clarity:plugin-line",{"title":81,"path":82,"stem":83,"icon":84},"WebSockets","/guide/advanced/websocket","1.guide/901.advanced/2.websocket","hugeicons:live-streaming-02",{"title":86,"path":87,"stem":88,"icon":89},"Nightly Builds","/guide/advanced/nightly","1.guide/901.advanced/9.nightly","game-icons:barn-owl","i-ph:book-open-duotone",{"title":92,"path":93,"stem":94,"children":95,"icon":97},"Utils","/utils","2.utils/0.index",[96,98,103,108,113,118,123,128],{"title":92,"path":93,"stem":94,"icon":97},"ph:function-bold",{"title":99,"path":100,"stem":101,"icon":102},"Request","/utils/request","2.utils/1.request","material-symbols-light:input",{"title":104,"path":105,"stem":106,"icon":107},"Response","/utils/response","2.utils/2.response","material-symbols-light:output",{"title":109,"path":110,"stem":111,"icon":112},"Cookie","/utils/cookie","2.utils/3.cookie","material-symbols:cookie-outline",{"title":114,"path":115,"stem":116,"icon":117},"Security","/utils/security","2.utils/4.security","wpf:key-security",{"title":119,"path":120,"stem":121,"icon":122},"Proxy","/utils/proxy","2.utils/5.proxy","arcticons:super-proxy",{"title":124,"path":125,"stem":126,"icon":127},"More utils","/utils/more","2.utils/9.more","mingcute:plus-line",{"title":129,"path":130,"stem":131,"icon":132},"Community","/utils/community","2.utils/99.community","lets-icons:external",{"title":134,"path":135,"stem":136,"children":137,"icon":139},"Examples","/examples","4.examples/0.index",[138,140,145,149,153,157],{"title":134,"path":135,"stem":136,"icon":139},"ph:code",{"title":141,"path":142,"stem":143,"icon":144},"Cookies","/examples/handle-cookie","4.examples/handle-cookie","ph:arrow-right",{"title":146,"path":147,"stem":148,"icon":144},"Sessions","/examples/handle-session","4.examples/handle-session",{"title":150,"path":151,"stem":152,"icon":144},"Static Assets","/examples/serve-static-assets","4.examples/serve-static-assets",{"title":154,"path":155,"stem":156,"icon":144},"Stream Response","/examples/stream-response","4.examples/stream-response",{"title":158,"path":159,"stem":160,"icon":144},"Validate Data","/examples/validate-data","4.examples/validate-data",{"title":162,"path":163,"stem":164,"children":165,"icon":167},"Migration","/migration","5.migration/0.index",[166],{"title":162,"path":163,"stem":164,"icon":167},"icons8:up-round",{"title":169,"path":170,"stem":171,"children":172},"Blog","/blog","99.blog",[173,176,180],{"title":169,"path":170,"stem":174,"icon":175},"99.blog/index","i-lucide-file-text",{"title":177,"path":178,"stem":179,"icon":175},"H3 1.8 - Towards the Edge of the Web","/blog/v1.8","99.blog/1.v1.8",{"title":181,"path":182,"stem":183,"icon":175},"H3 v2 beta","/blog/v2-beta","99.blog/2.v2-beta",{"id":185,"title":158,"body":186,"description":1946,"extension":1947,"meta":1948,"navigation":1949,"path":159,"seo":1950,"stem":160,"__hash__":1951},"content/4.examples/validate-data.md",{"type":187,"value":188,"toc":1938,"icon":144},"minimark",[189,193,204,209,212,235,273,283,293,298,308,648,655,666,673,677,685,1060,1066,1071,1080,1084,1088,1095,1387,1390,1430,1433,1442,1446,1449,1463,1469,1693,1696,1934],[190,191,192],"p",{},"When you receive data on your server, you must validate them. By validate, we mean that the shape of the received data must match the expected shape. It's important because you can't trust the data coming from unknown sources, like a user or an external API.",[194,195,196],"warning",{},[190,197,198,199,203],{},"\nDo not use type generics as a validation. Providing an interface to a utility like ",[200,201,202],"code",{},"readBody"," is not a validation. You must validate the data before using it.",[205,206,208],"h2",{"id":207},"utilities-for-validation","Utilities for Validation",[190,210,211],{},"H3 provide some utilities to help you to handle data validation. You will be able to validate:",[213,214,215,222,229],"ul",{},[216,217,218,219],"li",{},"query with ",[200,220,221],{},"getValidatedQuery",[216,223,224,225,228],{},"params with ",[200,226,227],{},"getValidatedRouterParams",".",[216,230,231,232],{},"body with ",[200,233,234],{},"readValidatedBody",[190,236,237,238,242,243,250,251,250,256,261,262,267,268,272],{},"H3 doesn't provide any validation library but it does support schemas coming from a ",[239,240,241],"strong",{},"Standard-Schema"," compatible one, like: ",[244,245,249],"a",{"href":246,"rel":247},"https://zod.dev",[248],"nofollow","Zod",", ",[244,252,255],{"href":253,"rel":254},"https://valibot.dev",[248],"Valibot",[244,257,260],{"href":258,"rel":259},"https://arktype.io/",[248],"ArkType",", etc... (for all compatible libraries please check ",[244,263,266],{"href":264,"rel":265},"https://github.com/standard-schema/standard-schema",[248],"their official repository","). If you want to use a validation library that is not compatible with Standard-Schema, you can still use it, but you will have to use parsing functions provided by the library itself (refer to the ",[244,269,271],{"href":270},"#safe-parsing","Safe Parsing"," section below).",[194,274,275],{},[190,276,277,278,282],{},"\nH3 is runtime agnostic. This means that you can use it in ",[244,279,281],{"href":280},"/adapters","any runtime",". But some validation libraries are not compatible with all runtimes.",[190,284,285,286,289,290,228],{},"Let's see how to validate data with ",[244,287,249],{"href":246,"rel":288},[248]," and ",[244,291,255],{"href":253,"rel":292},[248],[294,295,297],"h3",{"id":296},"validate-params","Validate Params",[190,299,300,301,303,304,307],{},"You can use ",[200,302,227],{}," to validate params and get the result, as a replacement of ",[200,305,306],{},"getRouterParams",":",[309,310,315],"pre",{"className":311,"code":312,"language":313,"meta":314,"style":314},"language-js shiki shiki-themes github-light github-dark github-dark","import { getValidatedRouterParams } from \"h3\";\nimport * as z from \"zod\";\nimport * as v from \"valibot\";\n\n// Example with Zod\nconst contentSchema = z.object({\n  topic: z.string().min(1),\n  uuid: z.string().uuid(),\n});\n// Example with Valibot\nconst contentSchema = v.object({\n  topic: v.pipe(v.string(), v.nonEmpty()),\n  uuid: v.pipe(v.string(), v.uuid()),\n});\n\nrouter.use(\n  // You must use a router to use params\n  \"/content/:topic/:uuid\",\n  async (event) => {\n    const params = await getValidatedRouterParams(event, contentSchema);\n    return `You are looking for content with topic \"${params.topic}\" and uuid \"${params.uuid}\".`;\n  },\n);\n","js","",[200,316,317,340,362,381,388,395,417,441,457,463,469,485,508,526,531,536,548,554,563,585,605,636,642],{"__ignoreMap":314},[318,319,322,326,330,333,337],"span",{"class":320,"line":321},"line",1,[318,323,325],{"class":324},"so5gQ","import",[318,327,329],{"class":328},"slsVL"," { getValidatedRouterParams } ",[318,331,332],{"class":324},"from",[318,334,336],{"class":335},"sfrk1"," \"h3\"",[318,338,339],{"class":328},";\n",[318,341,343,345,349,352,355,357,360],{"class":320,"line":342},2,[318,344,325],{"class":324},[318,346,348],{"class":347},"suiK_"," *",[318,350,351],{"class":324}," as",[318,353,354],{"class":328}," z ",[318,356,332],{"class":324},[318,358,359],{"class":335}," \"zod\"",[318,361,339],{"class":328},[318,363,365,367,369,371,374,376,379],{"class":320,"line":364},3,[318,366,325],{"class":324},[318,368,348],{"class":347},[318,370,351],{"class":324},[318,372,373],{"class":328}," v ",[318,375,332],{"class":324},[318,377,378],{"class":335}," \"valibot\"",[318,380,339],{"class":328},[318,382,384],{"class":320,"line":383},4,[318,385,387],{"emptyLinePlaceholder":386},true,"\n",[318,389,391],{"class":320,"line":390},5,[318,392,394],{"class":393},"sCsY4","// Example with Zod\n",[318,396,398,401,404,407,410,414],{"class":320,"line":397},6,[318,399,400],{"class":324},"const",[318,402,403],{"class":347}," contentSchema",[318,405,406],{"class":324}," =",[318,408,409],{"class":328}," z.",[318,411,413],{"class":412},"shcOC","object",[318,415,416],{"class":328},"({\n",[318,418,420,423,426,429,432,435,438],{"class":320,"line":419},7,[318,421,422],{"class":328},"  topic: z.",[318,424,425],{"class":412},"string",[318,427,428],{"class":328},"().",[318,430,431],{"class":412},"min",[318,433,434],{"class":328},"(",[318,436,437],{"class":347},"1",[318,439,440],{"class":328},"),\n",[318,442,444,447,449,451,454],{"class":320,"line":443},8,[318,445,446],{"class":328},"  uuid: z.",[318,448,425],{"class":412},[318,450,428],{"class":328},[318,452,453],{"class":412},"uuid",[318,455,456],{"class":328},"(),\n",[318,458,460],{"class":320,"line":459},9,[318,461,462],{"class":328},"});\n",[318,464,466],{"class":320,"line":465},10,[318,467,468],{"class":393},"// Example with Valibot\n",[318,470,472,474,476,478,481,483],{"class":320,"line":471},11,[318,473,400],{"class":324},[318,475,403],{"class":347},[318,477,406],{"class":324},[318,479,480],{"class":328}," v.",[318,482,413],{"class":412},[318,484,416],{"class":328},[318,486,488,491,494,497,499,502,505],{"class":320,"line":487},12,[318,489,490],{"class":328},"  topic: v.",[318,492,493],{"class":412},"pipe",[318,495,496],{"class":328},"(v.",[318,498,425],{"class":412},[318,500,501],{"class":328},"(), v.",[318,503,504],{"class":412},"nonEmpty",[318,506,507],{"class":328},"()),\n",[318,509,511,514,516,518,520,522,524],{"class":320,"line":510},13,[318,512,513],{"class":328},"  uuid: v.",[318,515,493],{"class":412},[318,517,496],{"class":328},[318,519,425],{"class":412},[318,521,501],{"class":328},[318,523,453],{"class":412},[318,525,507],{"class":328},[318,527,529],{"class":320,"line":528},14,[318,530,462],{"class":328},[318,532,534],{"class":320,"line":533},15,[318,535,387],{"emptyLinePlaceholder":386},[318,537,539,542,545],{"class":320,"line":538},16,[318,540,541],{"class":328},"router.",[318,543,544],{"class":412},"use",[318,546,547],{"class":328},"(\n",[318,549,551],{"class":320,"line":550},17,[318,552,553],{"class":393},"  // You must use a router to use params\n",[318,555,557,560],{"class":320,"line":556},18,[318,558,559],{"class":335},"  \"/content/:topic/:uuid\"",[318,561,562],{"class":328},",\n",[318,564,566,569,572,576,579,582],{"class":320,"line":565},19,[318,567,568],{"class":324},"  async",[318,570,571],{"class":328}," (",[318,573,575],{"class":574},"sQHwn","event",[318,577,578],{"class":328},") ",[318,580,581],{"class":324},"=>",[318,583,584],{"class":328}," {\n",[318,586,588,591,594,596,599,602],{"class":320,"line":587},20,[318,589,590],{"class":324},"    const",[318,592,593],{"class":347}," params",[318,595,406],{"class":324},[318,597,598],{"class":324}," await",[318,600,601],{"class":412}," getValidatedRouterParams",[318,603,604],{"class":328},"(event, contentSchema);\n",[318,606,608,611,614,617,619,622,625,627,629,631,634],{"class":320,"line":607},21,[318,609,610],{"class":324},"    return",[318,612,613],{"class":335}," `You are looking for content with topic \"${",[318,615,616],{"class":328},"params",[318,618,228],{"class":335},[318,620,621],{"class":328},"topic",[318,623,624],{"class":335},"}\" and uuid \"${",[318,626,616],{"class":328},[318,628,228],{"class":335},[318,630,453],{"class":328},[318,632,633],{"class":335},"}\".`",[318,635,339],{"class":328},[318,637,639],{"class":320,"line":638},22,[318,640,641],{"class":328},"  },\n",[318,643,645],{"class":320,"line":644},23,[318,646,647],{"class":328},");\n",[190,649,650,651,654],{},"If you send a valid request like ",[200,652,653],{},"/content/posts/123e4567-e89b-12d3-a456-426614174000"," to this event handler, you will get a response like this:",[309,656,660],{"className":657,"code":658,"language":659,"meta":314,"style":314},"language-txt shiki shiki-themes github-light github-dark github-dark","You are looking for content with topic \"posts\" and uuid \"123e4567-e89b-12d3-a456-426614174000\".\n","txt",[200,661,662],{"__ignoreMap":314},[318,663,664],{"class":320,"line":321},[318,665,658],{},[190,667,668,669,672],{},"If you send an invalid request and the validation fails, H3 will throw a ",[200,670,671],{},"400 Validation Error"," error. In the data of the error, you will find the validation errors you can use on your client to display a nice error message to your user.",[294,674,676],{"id":675},"validate-query","Validate Query",[190,678,300,679,681,682,307],{},[200,680,221],{}," to validate query and get the result, as a replacement of ",[200,683,684],{},"getQuery",[309,686,688],{"className":311,"code":687,"language":313,"meta":314,"style":314},"import { getValidatedQuery } from \"h3\";\nimport * as z from \"zod\";\nimport * as v from \"valibot\";\n\n// Example with Zod\nconst stringToNumber = z\n  .string()\n  .regex(/^\\d+$/, \"Must be a number string\")\n  .transform(Number);\nconst paginationSchema = z.object({\n  page: stringToNumber.optional().default(1),\n  size: stringToNumber.optional().default(10),\n});\n\n// Example with Valibot\nconst stringToNumber = v.pipe(\n  v.string(),\n  v.regex(/^\\d+$/, \"Must be a number string\"),\n  v.transform(Number),\n);\nconst paginationSchema = v.object({\n  page: v.optional(stringToNumber, 1),\n  size: v.optional(stringToNumber, 10),\n});\n\napp.use(async (event) => {\n  const query = await getValidatedQuery(event, paginationSchema);\n  return `You are on page ${query.page} with ${query.size} items per page.`;\n});\n",[200,689,690,703,719,735,739,743,755,765,796,806,821,840,858,862,866,870,884,893,917,926,930,944,958,971,976,981,1004,1023,1055],{"__ignoreMap":314},[318,691,692,694,697,699,701],{"class":320,"line":321},[318,693,325],{"class":324},[318,695,696],{"class":328}," { getValidatedQuery } ",[318,698,332],{"class":324},[318,700,336],{"class":335},[318,702,339],{"class":328},[318,704,705,707,709,711,713,715,717],{"class":320,"line":342},[318,706,325],{"class":324},[318,708,348],{"class":347},[318,710,351],{"class":324},[318,712,354],{"class":328},[318,714,332],{"class":324},[318,716,359],{"class":335},[318,718,339],{"class":328},[318,720,721,723,725,727,729,731,733],{"class":320,"line":364},[318,722,325],{"class":324},[318,724,348],{"class":347},[318,726,351],{"class":324},[318,728,373],{"class":328},[318,730,332],{"class":324},[318,732,378],{"class":335},[318,734,339],{"class":328},[318,736,737],{"class":320,"line":383},[318,738,387],{"emptyLinePlaceholder":386},[318,740,741],{"class":320,"line":390},[318,742,394],{"class":393},[318,744,745,747,750,752],{"class":320,"line":397},[318,746,400],{"class":324},[318,748,749],{"class":347}," stringToNumber",[318,751,406],{"class":324},[318,753,754],{"class":328}," z\n",[318,756,757,760,762],{"class":320,"line":419},[318,758,759],{"class":328},"  .",[318,761,425],{"class":412},[318,763,764],{"class":328},"()\n",[318,766,767,769,772,774,777,780,783,786,788,790,793],{"class":320,"line":443},[318,768,759],{"class":328},[318,770,771],{"class":412},"regex",[318,773,434],{"class":328},[318,775,776],{"class":335},"/",[318,778,779],{"class":324},"^",[318,781,782],{"class":347},"\\d",[318,784,785],{"class":324},"+$",[318,787,776],{"class":335},[318,789,250],{"class":328},[318,791,792],{"class":335},"\"Must be a number string\"",[318,794,795],{"class":328},")\n",[318,797,798,800,803],{"class":320,"line":459},[318,799,759],{"class":328},[318,801,802],{"class":412},"transform",[318,804,805],{"class":328},"(Number);\n",[318,807,808,810,813,815,817,819],{"class":320,"line":465},[318,809,400],{"class":324},[318,811,812],{"class":347}," paginationSchema",[318,814,406],{"class":324},[318,816,409],{"class":328},[318,818,413],{"class":412},[318,820,416],{"class":328},[318,822,823,826,829,831,834,836,838],{"class":320,"line":471},[318,824,825],{"class":328},"  page: stringToNumber.",[318,827,828],{"class":412},"optional",[318,830,428],{"class":328},[318,832,833],{"class":412},"default",[318,835,434],{"class":328},[318,837,437],{"class":347},[318,839,440],{"class":328},[318,841,842,845,847,849,851,853,856],{"class":320,"line":487},[318,843,844],{"class":328},"  size: stringToNumber.",[318,846,828],{"class":412},[318,848,428],{"class":328},[318,850,833],{"class":412},[318,852,434],{"class":328},[318,854,855],{"class":347},"10",[318,857,440],{"class":328},[318,859,860],{"class":320,"line":510},[318,861,462],{"class":328},[318,863,864],{"class":320,"line":528},[318,865,387],{"emptyLinePlaceholder":386},[318,867,868],{"class":320,"line":533},[318,869,468],{"class":393},[318,871,872,874,876,878,880,882],{"class":320,"line":538},[318,873,400],{"class":324},[318,875,749],{"class":347},[318,877,406],{"class":324},[318,879,480],{"class":328},[318,881,493],{"class":412},[318,883,547],{"class":328},[318,885,886,889,891],{"class":320,"line":550},[318,887,888],{"class":328},"  v.",[318,890,425],{"class":412},[318,892,456],{"class":328},[318,894,895,897,899,901,903,905,907,909,911,913,915],{"class":320,"line":556},[318,896,888],{"class":328},[318,898,771],{"class":412},[318,900,434],{"class":328},[318,902,776],{"class":335},[318,904,779],{"class":324},[318,906,782],{"class":347},[318,908,785],{"class":324},[318,910,776],{"class":335},[318,912,250],{"class":328},[318,914,792],{"class":335},[318,916,440],{"class":328},[318,918,919,921,923],{"class":320,"line":565},[318,920,888],{"class":328},[318,922,802],{"class":412},[318,924,925],{"class":328},"(Number),\n",[318,927,928],{"class":320,"line":587},[318,929,647],{"class":328},[318,931,932,934,936,938,940,942],{"class":320,"line":607},[318,933,400],{"class":324},[318,935,812],{"class":347},[318,937,406],{"class":324},[318,939,480],{"class":328},[318,941,413],{"class":412},[318,943,416],{"class":328},[318,945,946,949,951,954,956],{"class":320,"line":638},[318,947,948],{"class":328},"  page: v.",[318,950,828],{"class":412},[318,952,953],{"class":328},"(stringToNumber, ",[318,955,437],{"class":347},[318,957,440],{"class":328},[318,959,960,963,965,967,969],{"class":320,"line":644},[318,961,962],{"class":328},"  size: v.",[318,964,828],{"class":412},[318,966,953],{"class":328},[318,968,855],{"class":347},[318,970,440],{"class":328},[318,972,974],{"class":320,"line":973},24,[318,975,462],{"class":328},[318,977,979],{"class":320,"line":978},25,[318,980,387],{"emptyLinePlaceholder":386},[318,982,984,987,989,991,994,996,998,1000,1002],{"class":320,"line":983},26,[318,985,986],{"class":328},"app.",[318,988,544],{"class":412},[318,990,434],{"class":328},[318,992,993],{"class":324},"async",[318,995,571],{"class":328},[318,997,575],{"class":574},[318,999,578],{"class":328},[318,1001,581],{"class":324},[318,1003,584],{"class":328},[318,1005,1007,1010,1013,1015,1017,1020],{"class":320,"line":1006},27,[318,1008,1009],{"class":324},"  const",[318,1011,1012],{"class":347}," query",[318,1014,406],{"class":324},[318,1016,598],{"class":324},[318,1018,1019],{"class":412}," getValidatedQuery",[318,1021,1022],{"class":328},"(event, paginationSchema);\n",[318,1024,1026,1029,1032,1035,1037,1040,1043,1045,1047,1050,1053],{"class":320,"line":1025},28,[318,1027,1028],{"class":324},"  return",[318,1030,1031],{"class":335}," `You are on page ${",[318,1033,1034],{"class":328},"query",[318,1036,228],{"class":335},[318,1038,1039],{"class":328},"page",[318,1041,1042],{"class":335},"} with ${",[318,1044,1034],{"class":328},[318,1046,228],{"class":335},[318,1048,1049],{"class":328},"size",[318,1051,1052],{"class":335},"} items per page.`",[318,1054,339],{"class":328},[318,1056,1058],{"class":320,"line":1057},29,[318,1059,462],{"class":328},[190,1061,1062,1063,1065],{},"As you may have noticed, compared to the ",[200,1064,227],{}," example, we can leverage validation libraries to transform the incoming data. In this case, we transform the string representation of a number into a real number, which is useful for things like content pagination.",[190,1067,650,1068,654],{},[200,1069,1070],{},"/?page=2&size=20",[309,1072,1074],{"className":657,"code":1073,"language":659,"meta":314,"style":314},"You are on page 2 with 20 items per page.\n",[200,1075,1076],{"__ignoreMap":314},[318,1077,1078],{"class":320,"line":321},[318,1079,1073],{},[190,1081,668,1082,672],{},[200,1083,671],{},[294,1085,1087],{"id":1086},"validate-body","Validate Body",[190,1089,300,1090,1092,1093,307],{},[200,1091,234],{}," to validate body and get the result, as a replacement of ",[200,1094,202],{},[309,1096,1098],{"className":311,"code":1097,"language":313,"meta":314,"style":314},"import { readValidatedBody } from \"h3\";\nimport { z } from \"zod\";\nimport * as v from \"valibot\";\n\n// Example with Zod\nconst userSchema = z.object({\n  name: z.string().min(3).max(20),\n  age: z.number({ coerce: true }).positive().int(),\n});\n\n// Example with Valibot\nconst userSchema = v.object({\n  name: v.pipe(v.string(), v.minLength(3), v.maxLength(20)),\n  age: v.pipe(v.number(), v.integer(), v.minValue(0)),\n});\n\napp.use(async (event) => {\n  const body = await readValidatedBody(event, userSchema);\n  return `Hello ${body.name}! You are ${body.age} years old.`;\n});\n",[200,1099,1100,1113,1126,1142,1146,1150,1165,1194,1221,1225,1229,1233,1247,1280,1308,1312,1316,1336,1353,1383],{"__ignoreMap":314},[318,1101,1102,1104,1107,1109,1111],{"class":320,"line":321},[318,1103,325],{"class":324},[318,1105,1106],{"class":328}," { readValidatedBody } ",[318,1108,332],{"class":324},[318,1110,336],{"class":335},[318,1112,339],{"class":328},[318,1114,1115,1117,1120,1122,1124],{"class":320,"line":342},[318,1116,325],{"class":324},[318,1118,1119],{"class":328}," { z } ",[318,1121,332],{"class":324},[318,1123,359],{"class":335},[318,1125,339],{"class":328},[318,1127,1128,1130,1132,1134,1136,1138,1140],{"class":320,"line":364},[318,1129,325],{"class":324},[318,1131,348],{"class":347},[318,1133,351],{"class":324},[318,1135,373],{"class":328},[318,1137,332],{"class":324},[318,1139,378],{"class":335},[318,1141,339],{"class":328},[318,1143,1144],{"class":320,"line":383},[318,1145,387],{"emptyLinePlaceholder":386},[318,1147,1148],{"class":320,"line":390},[318,1149,394],{"class":393},[318,1151,1152,1154,1157,1159,1161,1163],{"class":320,"line":397},[318,1153,400],{"class":324},[318,1155,1156],{"class":347}," userSchema",[318,1158,406],{"class":324},[318,1160,409],{"class":328},[318,1162,413],{"class":412},[318,1164,416],{"class":328},[318,1166,1167,1170,1172,1174,1176,1178,1181,1184,1187,1189,1192],{"class":320,"line":419},[318,1168,1169],{"class":328},"  name: z.",[318,1171,425],{"class":412},[318,1173,428],{"class":328},[318,1175,431],{"class":412},[318,1177,434],{"class":328},[318,1179,1180],{"class":347},"3",[318,1182,1183],{"class":328},").",[318,1185,1186],{"class":412},"max",[318,1188,434],{"class":328},[318,1190,1191],{"class":347},"20",[318,1193,440],{"class":328},[318,1195,1196,1199,1202,1205,1208,1211,1214,1216,1219],{"class":320,"line":443},[318,1197,1198],{"class":328},"  age: z.",[318,1200,1201],{"class":412},"number",[318,1203,1204],{"class":328},"({ coerce: ",[318,1206,1207],{"class":347},"true",[318,1209,1210],{"class":328}," }).",[318,1212,1213],{"class":412},"positive",[318,1215,428],{"class":328},[318,1217,1218],{"class":412},"int",[318,1220,456],{"class":328},[318,1222,1223],{"class":320,"line":459},[318,1224,462],{"class":328},[318,1226,1227],{"class":320,"line":465},[318,1228,387],{"emptyLinePlaceholder":386},[318,1230,1231],{"class":320,"line":471},[318,1232,468],{"class":393},[318,1234,1235,1237,1239,1241,1243,1245],{"class":320,"line":487},[318,1236,400],{"class":324},[318,1238,1156],{"class":347},[318,1240,406],{"class":324},[318,1242,480],{"class":328},[318,1244,413],{"class":412},[318,1246,416],{"class":328},[318,1248,1249,1252,1254,1256,1258,1260,1263,1265,1267,1270,1273,1275,1277],{"class":320,"line":510},[318,1250,1251],{"class":328},"  name: v.",[318,1253,493],{"class":412},[318,1255,496],{"class":328},[318,1257,425],{"class":412},[318,1259,501],{"class":328},[318,1261,1262],{"class":412},"minLength",[318,1264,434],{"class":328},[318,1266,1180],{"class":347},[318,1268,1269],{"class":328},"), v.",[318,1271,1272],{"class":412},"maxLength",[318,1274,434],{"class":328},[318,1276,1191],{"class":347},[318,1278,1279],{"class":328},")),\n",[318,1281,1282,1285,1287,1289,1291,1293,1296,1298,1301,1303,1306],{"class":320,"line":528},[318,1283,1284],{"class":328},"  age: v.",[318,1286,493],{"class":412},[318,1288,496],{"class":328},[318,1290,1201],{"class":412},[318,1292,501],{"class":328},[318,1294,1295],{"class":412},"integer",[318,1297,501],{"class":328},[318,1299,1300],{"class":412},"minValue",[318,1302,434],{"class":328},[318,1304,1305],{"class":347},"0",[318,1307,1279],{"class":328},[318,1309,1310],{"class":320,"line":533},[318,1311,462],{"class":328},[318,1313,1314],{"class":320,"line":538},[318,1315,387],{"emptyLinePlaceholder":386},[318,1317,1318,1320,1322,1324,1326,1328,1330,1332,1334],{"class":320,"line":550},[318,1319,986],{"class":328},[318,1321,544],{"class":412},[318,1323,434],{"class":328},[318,1325,993],{"class":324},[318,1327,571],{"class":328},[318,1329,575],{"class":574},[318,1331,578],{"class":328},[318,1333,581],{"class":324},[318,1335,584],{"class":328},[318,1337,1338,1340,1343,1345,1347,1350],{"class":320,"line":556},[318,1339,1009],{"class":324},[318,1341,1342],{"class":347}," body",[318,1344,406],{"class":324},[318,1346,598],{"class":324},[318,1348,1349],{"class":412}," readValidatedBody",[318,1351,1352],{"class":328},"(event, userSchema);\n",[318,1354,1355,1357,1360,1363,1365,1368,1371,1373,1375,1378,1381],{"class":320,"line":565},[318,1356,1028],{"class":324},[318,1358,1359],{"class":335}," `Hello ${",[318,1361,1362],{"class":328},"body",[318,1364,228],{"class":335},[318,1366,1367],{"class":328},"name",[318,1369,1370],{"class":335},"}! You are ${",[318,1372,1362],{"class":328},[318,1374,228],{"class":335},[318,1376,1377],{"class":328},"age",[318,1379,1380],{"class":335},"} years old.`",[318,1382,339],{"class":328},[318,1384,1385],{"class":320,"line":587},[318,1386,462],{"class":328},[190,1388,1389],{},"If you send a valid POST request with a JSON body like this:",[309,1391,1395],{"className":1392,"code":1393,"language":1394,"meta":314,"style":314},"language-json shiki shiki-themes github-light github-dark github-dark","{\n  \"name\": \"John\",\n  \"age\": 42\n}\n","json",[200,1396,1397,1402,1415,1425],{"__ignoreMap":314},[318,1398,1399],{"class":320,"line":321},[318,1400,1401],{"class":328},"{\n",[318,1403,1404,1407,1410,1413],{"class":320,"line":342},[318,1405,1406],{"class":347},"  \"name\"",[318,1408,1409],{"class":328},": ",[318,1411,1412],{"class":335},"\"John\"",[318,1414,562],{"class":328},[318,1416,1417,1420,1422],{"class":320,"line":364},[318,1418,1419],{"class":347},"  \"age\"",[318,1421,1409],{"class":328},[318,1423,1424],{"class":347},"42\n",[318,1426,1427],{"class":320,"line":383},[318,1428,1429],{"class":328},"}\n",[190,1431,1432],{},"You will get a response like this:",[309,1434,1436],{"className":657,"code":1435,"language":659,"meta":314,"style":314},"Hello John! You are 42 years old.\n",[200,1437,1438],{"__ignoreMap":314},[318,1439,1440],{"class":320,"line":321},[318,1441,1435],{},[190,1443,668,1444,672],{},[200,1445,671],{},[205,1447,271],{"id":1448},"safe-parsing",[190,1450,1451,1452,250,1454,1456,1457,1459,1460,1462],{},"By default if a schema is directly provided as e second argument for each validation utility (",[200,1453,227],{},[200,1455,221],{},", and ",[200,1458,234],{},") it will throw a ",[200,1461,671],{}," error if the validation fails, but in some cases you may want to handle the validation errors yourself. For this you should provide the actual safe validation function as the second argument, depending on the validation library you are using.",[190,1464,1465,1466,1468],{},"Going back to the first example with ",[200,1467,227],{},", for Zod it would look like this:",[309,1470,1474],{"className":1471,"code":1472,"language":1473,"meta":314,"style":314},"language-ts shiki shiki-themes github-light github-dark github-dark","import { getValidatedRouterParams } from \"h3\";\nimport { z } from \"zod/v4\";\n\nconst contentSchema = z.object({\n  topic: z.string().min(1),\n  uuid: z.string().uuid(),\n});\n\nrouter.use(\"/content/:topic/:uuid\", async (event) => {\n  const params = await getValidatedRouterParams(event, contentSchema.safeParse);\n  if (!params.success) {\n    // Handle validation errors\n    return `Validation failed:\\n${z.prettifyError(params.error)}`;\n  }\n  return `You are looking for content with topic \"${params.data.topic}\" and uuid \"${params.data.uuid}\".`;\n});\n","ts",[200,1475,1476,1488,1501,1505,1519,1535,1547,1551,1555,1580,1595,1608,1613,1651,1656,1689],{"__ignoreMap":314},[318,1477,1478,1480,1482,1484,1486],{"class":320,"line":321},[318,1479,325],{"class":324},[318,1481,329],{"class":328},[318,1483,332],{"class":324},[318,1485,336],{"class":335},[318,1487,339],{"class":328},[318,1489,1490,1492,1494,1496,1499],{"class":320,"line":342},[318,1491,325],{"class":324},[318,1493,1119],{"class":328},[318,1495,332],{"class":324},[318,1497,1498],{"class":335}," \"zod/v4\"",[318,1500,339],{"class":328},[318,1502,1503],{"class":320,"line":364},[318,1504,387],{"emptyLinePlaceholder":386},[318,1506,1507,1509,1511,1513,1515,1517],{"class":320,"line":383},[318,1508,400],{"class":324},[318,1510,403],{"class":347},[318,1512,406],{"class":324},[318,1514,409],{"class":328},[318,1516,413],{"class":412},[318,1518,416],{"class":328},[318,1520,1521,1523,1525,1527,1529,1531,1533],{"class":320,"line":390},[318,1522,422],{"class":328},[318,1524,425],{"class":412},[318,1526,428],{"class":328},[318,1528,431],{"class":412},[318,1530,434],{"class":328},[318,1532,437],{"class":347},[318,1534,440],{"class":328},[318,1536,1537,1539,1541,1543,1545],{"class":320,"line":397},[318,1538,446],{"class":328},[318,1540,425],{"class":412},[318,1542,428],{"class":328},[318,1544,453],{"class":412},[318,1546,456],{"class":328},[318,1548,1549],{"class":320,"line":419},[318,1550,462],{"class":328},[318,1552,1553],{"class":320,"line":443},[318,1554,387],{"emptyLinePlaceholder":386},[318,1556,1557,1559,1561,1563,1566,1568,1570,1572,1574,1576,1578],{"class":320,"line":459},[318,1558,541],{"class":328},[318,1560,544],{"class":412},[318,1562,434],{"class":328},[318,1564,1565],{"class":335},"\"/content/:topic/:uuid\"",[318,1567,250],{"class":328},[318,1569,993],{"class":324},[318,1571,571],{"class":328},[318,1573,575],{"class":574},[318,1575,578],{"class":328},[318,1577,581],{"class":324},[318,1579,584],{"class":328},[318,1581,1582,1584,1586,1588,1590,1592],{"class":320,"line":465},[318,1583,1009],{"class":324},[318,1585,593],{"class":347},[318,1587,406],{"class":324},[318,1589,598],{"class":324},[318,1591,601],{"class":412},[318,1593,1594],{"class":328},"(event, contentSchema.safeParse);\n",[318,1596,1597,1600,1602,1605],{"class":320,"line":471},[318,1598,1599],{"class":324},"  if",[318,1601,571],{"class":328},[318,1603,1604],{"class":324},"!",[318,1606,1607],{"class":328},"params.success) {\n",[318,1609,1610],{"class":320,"line":487},[318,1611,1612],{"class":393},"    // Handle validation errors\n",[318,1614,1615,1617,1620,1623,1626,1629,1631,1634,1636,1638,1640,1643,1646,1649],{"class":320,"line":510},[318,1616,610],{"class":324},[318,1618,1619],{"class":335}," `Validation failed:",[318,1621,1622],{"class":347},"\\n",[318,1624,1625],{"class":335},"${",[318,1627,1628],{"class":328},"z",[318,1630,228],{"class":335},[318,1632,1633],{"class":412},"prettifyError",[318,1635,434],{"class":335},[318,1637,616],{"class":328},[318,1639,228],{"class":335},[318,1641,1642],{"class":328},"error",[318,1644,1645],{"class":335},")",[318,1647,1648],{"class":335},"}`",[318,1650,339],{"class":328},[318,1652,1653],{"class":320,"line":528},[318,1654,1655],{"class":328},"  }\n",[318,1657,1658,1660,1662,1664,1666,1669,1671,1673,1675,1677,1679,1681,1683,1685,1687],{"class":320,"line":533},[318,1659,1028],{"class":324},[318,1661,613],{"class":335},[318,1663,616],{"class":328},[318,1665,228],{"class":335},[318,1667,1668],{"class":328},"data",[318,1670,228],{"class":335},[318,1672,621],{"class":328},[318,1674,624],{"class":335},[318,1676,616],{"class":328},[318,1678,228],{"class":335},[318,1680,1668],{"class":328},[318,1682,228],{"class":335},[318,1684,453],{"class":328},[318,1686,633],{"class":335},[318,1688,339],{"class":328},[318,1690,1691],{"class":320,"line":538},[318,1692,462],{"class":328},[190,1694,1695],{},"And for Valibot, it would look like this:",[309,1697,1699],{"className":1471,"code":1698,"language":1473,"meta":314,"style":314},"import { getValidatedRouterParams } from \"h3\";\nimport * as v from \"valibot\";\n\nconst contentSchema = v.object({\n  topic: v.pipe(v.string(), v.nonEmpty()),\n  uuid: v.pipe(v.string(), v.uuid()),\n});\n\nrouter.use(\"/content/:topic/:uuid\", async (event) => {\n  const params = await getValidatedRouterParams(\n    event,\n    v.safeParser(contentSchema),\n  );\n  if (!params.success) {\n    // Handle validation errors\n    return `Validation failed:\\n${v.summarize(params.issues)}`;\n  }\n  return `You are looking for content with topic \"${params.output.topic}\" and uuid \"${params.output.uuid}\".`;\n});\n",[200,1700,1701,1713,1729,1733,1747,1763,1779,1783,1787,1811,1825,1830,1841,1846,1856,1860,1893,1897,1930],{"__ignoreMap":314},[318,1702,1703,1705,1707,1709,1711],{"class":320,"line":321},[318,1704,325],{"class":324},[318,1706,329],{"class":328},[318,1708,332],{"class":324},[318,1710,336],{"class":335},[318,1712,339],{"class":328},[318,1714,1715,1717,1719,1721,1723,1725,1727],{"class":320,"line":342},[318,1716,325],{"class":324},[318,1718,348],{"class":347},[318,1720,351],{"class":324},[318,1722,373],{"class":328},[318,1724,332],{"class":324},[318,1726,378],{"class":335},[318,1728,339],{"class":328},[318,1730,1731],{"class":320,"line":364},[318,1732,387],{"emptyLinePlaceholder":386},[318,1734,1735,1737,1739,1741,1743,1745],{"class":320,"line":383},[318,1736,400],{"class":324},[318,1738,403],{"class":347},[318,1740,406],{"class":324},[318,1742,480],{"class":328},[318,1744,413],{"class":412},[318,1746,416],{"class":328},[318,1748,1749,1751,1753,1755,1757,1759,1761],{"class":320,"line":390},[318,1750,490],{"class":328},[318,1752,493],{"class":412},[318,1754,496],{"class":328},[318,1756,425],{"class":412},[318,1758,501],{"class":328},[318,1760,504],{"class":412},[318,1762,507],{"class":328},[318,1764,1765,1767,1769,1771,1773,1775,1777],{"class":320,"line":397},[318,1766,513],{"class":328},[318,1768,493],{"class":412},[318,1770,496],{"class":328},[318,1772,425],{"class":412},[318,1774,501],{"class":328},[318,1776,453],{"class":412},[318,1778,507],{"class":328},[318,1780,1781],{"class":320,"line":419},[318,1782,462],{"class":328},[318,1784,1785],{"class":320,"line":443},[318,1786,387],{"emptyLinePlaceholder":386},[318,1788,1789,1791,1793,1795,1797,1799,1801,1803,1805,1807,1809],{"class":320,"line":459},[318,1790,541],{"class":328},[318,1792,544],{"class":412},[318,1794,434],{"class":328},[318,1796,1565],{"class":335},[318,1798,250],{"class":328},[318,1800,993],{"class":324},[318,1802,571],{"class":328},[318,1804,575],{"class":574},[318,1806,578],{"class":328},[318,1808,581],{"class":324},[318,1810,584],{"class":328},[318,1812,1813,1815,1817,1819,1821,1823],{"class":320,"line":465},[318,1814,1009],{"class":324},[318,1816,593],{"class":347},[318,1818,406],{"class":324},[318,1820,598],{"class":324},[318,1822,601],{"class":412},[318,1824,547],{"class":328},[318,1826,1827],{"class":320,"line":471},[318,1828,1829],{"class":328},"    event,\n",[318,1831,1832,1835,1838],{"class":320,"line":487},[318,1833,1834],{"class":328},"    v.",[318,1836,1837],{"class":412},"safeParser",[318,1839,1840],{"class":328},"(contentSchema),\n",[318,1842,1843],{"class":320,"line":510},[318,1844,1845],{"class":328},"  );\n",[318,1847,1848,1850,1852,1854],{"class":320,"line":528},[318,1849,1599],{"class":324},[318,1851,571],{"class":328},[318,1853,1604],{"class":324},[318,1855,1607],{"class":328},[318,1857,1858],{"class":320,"line":533},[318,1859,1612],{"class":393},[318,1861,1862,1864,1866,1868,1870,1873,1875,1878,1880,1882,1884,1887,1889,1891],{"class":320,"line":538},[318,1863,610],{"class":324},[318,1865,1619],{"class":335},[318,1867,1622],{"class":347},[318,1869,1625],{"class":335},[318,1871,1872],{"class":328},"v",[318,1874,228],{"class":335},[318,1876,1877],{"class":412},"summarize",[318,1879,434],{"class":335},[318,1881,616],{"class":328},[318,1883,228],{"class":335},[318,1885,1886],{"class":328},"issues",[318,1888,1645],{"class":335},[318,1890,1648],{"class":335},[318,1892,339],{"class":328},[318,1894,1895],{"class":320,"line":550},[318,1896,1655],{"class":328},[318,1898,1899,1901,1903,1905,1907,1910,1912,1914,1916,1918,1920,1922,1924,1926,1928],{"class":320,"line":556},[318,1900,1028],{"class":324},[318,1902,613],{"class":335},[318,1904,616],{"class":328},[318,1906,228],{"class":335},[318,1908,1909],{"class":328},"output",[318,1911,228],{"class":335},[318,1913,621],{"class":328},[318,1915,624],{"class":335},[318,1917,616],{"class":328},[318,1919,228],{"class":335},[318,1921,1909],{"class":328},[318,1923,228],{"class":335},[318,1925,453],{"class":328},[318,1927,633],{"class":335},[318,1929,339],{"class":328},[318,1931,1932],{"class":320,"line":565},[318,1933,462],{"class":328},[1935,1936,1937],"style",{},"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}html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sfrk1, html code.shiki .sfrk1{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}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 .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}",{"title":314,"searchDepth":342,"depth":342,"links":1939},[1940,1945],{"id":207,"depth":342,"text":208,"children":1941},[1942,1943,1944],{"id":296,"depth":364,"text":297},{"id":675,"depth":364,"text":676},{"id":1086,"depth":364,"text":1087},{"id":1448,"depth":342,"text":271},"Ensure that your data are valid and safe before processing them.","md",{"icon":144},{"icon":144},{"title":158,"description":1946},"hk5OoLcS6AnzhOq3EWMyzDkpi0ATpshadno2MJyY8qc",[1953,1955],{"title":154,"path":155,"stem":156,"description":1954,"icon":144,"children":-1},"Stream response to the client.",{"title":162,"path":163,"stem":164,"description":314,"icon":167,"children":-1},1768646387236]