[{"data":1,"prerenderedAt":2410},["ShallowReactive",2],{"headless-navigation":3,"mdc-o8y00b-key":62,"headless-version":104,"\u002Fdocs\u002Fheadless\u002Fusage\u002Fapi-builder":105,"\u002Fdocs\u002Fheadless\u002Fusage\u002Fapi-builder-surround":2407},[4,19,37],{"title":5,"path":6,"stem":7,"children":8},"Getting Started","\u002Fdocs\u002Fheadless\u002Fgetting-started","1.docs\u002F5.headless\u002F1.getting-started\u002F1.index",[9,11,15],{"title":10,"path":6,"stem":7},"Introduction",{"title":12,"path":13,"stem":14},"Installation","\u002Fdocs\u002Fheadless\u002Fgetting-started\u002Finstallation","1.docs\u002F5.headless\u002F1.getting-started\u002F2.installation",{"title":16,"path":17,"stem":18},"Version Migration","\u002Fdocs\u002Fheadless\u002Fgetting-started\u002Fmigration","1.docs\u002F5.headless\u002F1.getting-started\u002F3.migration",{"title":20,"path":21,"stem":22,"children":23,"page":36},"Configuration","\u002Fdocs\u002Fheadless\u002Fconfiguration","1.docs\u002F5.headless\u002F2.configuration",[24,28,32],{"title":25,"path":26,"stem":27},"Authentication","\u002Fdocs\u002Fheadless\u002Fconfiguration\u002Fauthentication","1.docs\u002F5.headless\u002F2.configuration\u002F1.authentication",{"title":29,"path":30,"stem":31},"CORS","\u002Fdocs\u002Fheadless\u002Fconfiguration\u002Fcors","1.docs\u002F5.headless\u002F2.configuration\u002F2.cors",{"title":33,"path":34,"stem":35},"Panel Configuration","\u002Fdocs\u002Fheadless\u002Fconfiguration\u002Fpanel","1.docs\u002F5.headless\u002F2.configuration\u002F3.panel",false,{"title":38,"path":39,"stem":40,"children":41,"page":36},"Usage","\u002Fdocs\u002Fheadless\u002Fusage","1.docs\u002F5.headless\u002F3.usage",[42,46,50,54,58],{"title":43,"path":44,"stem":45},"KQL (Kirby Query Language)","\u002Fdocs\u002Fheadless\u002Fusage\u002Fkql","1.docs\u002F5.headless\u002F3.usage\u002F1.kql",{"title":47,"path":48,"stem":49},"JSON Templates","\u002Fdocs\u002Fheadless\u002Fusage\u002Fjson-templates","1.docs\u002F5.headless\u002F3.usage\u002F2.json-templates",{"title":51,"path":52,"stem":53},"Field Methods","\u002Fdocs\u002Fheadless\u002Fusage\u002Ffield-methods","1.docs\u002F5.headless\u002F3.usage\u002F3.field-methods",{"title":55,"path":56,"stem":57},"Page Methods","\u002Fdocs\u002Fheadless\u002Fusage\u002Fpage-methods","1.docs\u002F5.headless\u002F3.usage\u002F4.page-methods",{"title":59,"path":60,"stem":61},"API Builder","\u002Fdocs\u002Fheadless\u002Fusage\u002Fapi-builder","1.docs\u002F5.headless\u002F3.usage\u002F5.api-builder",{"data":63,"body":64},{},{"type":65,"children":66},"root",[67],{"type":68,"tag":69,"props":70,"children":71},"element","p",{},[72,75,84,86,93,95,102],{"type":73,"value":74},"text","Kirby Tools is built on ",{"type":68,"tag":76,"props":77,"children":81},"a",{"href":78,"rel":79},"https:\u002F\u002Fgetkirby.com",[80],"nofollow",[82],{"type":73,"value":83},"Kirby",{"type":73,"value":85}," – with gratitude to the team and community who make it. Help me improve the plugins: share feedback in ",{"type":68,"tag":76,"props":87,"children":90},{"href":88,"rel":89},"https:\u002F\u002Fgithub.com\u002Fkirby-tools\u002Fcommunity\u002Fdiscussions",[80],[91],{"type":73,"value":92},"Discussions",{"type":73,"value":94}," or report bugs via ",{"type":68,"tag":76,"props":96,"children":99},{"href":97,"rel":98},"https:\u002F\u002Fgithub.com\u002Fkirby-tools\u002Fcommunity\u002Fissues",[80],[100],{"type":73,"value":101},"Issues",{"type":73,"value":103},".",null,{"id":106,"title":59,"body":107,"description":2402,"extension":2403,"meta":2404,"navigation":257,"path":60,"seo":2405,"stem":61,"__hash__":2406},"docs\u002F1.docs\u002F5.headless\u002F3.usage\u002F5.api-builder.md",{"type":108,"value":109,"toc":2382},"minimark",[110,113,118,130,141,187,209,213,218,225,423,427,430,588,592,599,917,921,928,938,943,962,1031,1037,1058,1228,1245,1250,1253,1270,1348,1354,1380,1477,1482,1500,1578,1582,1585,1914,1918,1927,1991,1994,2027,2044,2048,2052,2378],[69,111,112],{},"Kirby Headless includes an Express-style API builder for creating custom routes with middleware support. This allows you to reuse logic like authentication, validation, and error handling across multiple routes.",[114,115,117],"h2",{"id":116},"api-builder-basics","API Builder Basics",[69,119,120,121,125,126,129],{},"The API builder is provided by the ",[122,123,124],"code",{},"JohannSchopplich\\Headless\\Api\\Api"," class. Use ",[122,127,128],{},"Api::createHandler()"," to chain middleware functions that execute sequentially before your final route handler.",[69,131,132,133,136,137,140],{},"Middleware functions receive a ",[122,134,135],{},"$context"," array and the route ",[122,138,139],{},"$args",". What a middleware returns decides what happens next:",[142,143,144,157],"table",{},[145,146,147],"thead",{},[148,149,150,154],"tr",{},[151,152,153],"th",{},"Return value",[151,155,156],{},"Effect",[158,159,160,171,179],"tbody",{},[148,161,162,168],{},[163,164,165],"td",{},[122,166,167],{},"null",[163,169,170],{},"The next middleware runs with the context unchanged",[148,172,173,176],{},[163,174,175],{},"An array",[163,177,178],{},"It is merged into the context every later middleware receives",[148,180,181,184],{},[163,182,183],{},"Anything else",[163,185,186],{},"It is the answer and ends the chain",[69,188,189,190,193,194,197,198,201,202,193,205,208],{},"The last row covers everything Kirby's router knows how to send: a ",[122,191,192],{},"Response",", a ",[122,195,196],{},"Responder"," (what ",[122,199,200],{},"$kirby->response()"," returns), a ",[122,203,204],{},"File",[122,206,207],{},"Page",", or a plain string.",[114,210,212],{"id":211},"creating-routes","Creating Routes",[214,215,217],"h3",{"id":216},"basic-route","Basic Route",[69,219,220,221,224],{},"Create a simple API route accessible at ",[122,222,223],{},"\u002Fapi\u002Fhello",":",[226,227,233],"pre",{"className":228,"code":229,"filename":230,"language":231,"meta":232,"style":232},"language-php shiki shiki-themes github-light github-light github-dark","use JohannSchopplich\\Headless\\Api\\Api;\n\nreturn [\n    'routes' => [\n        [\n            'pattern' => 'api\u002Fhello',\n            'method' => 'GET',\n            'action' => Api::createHandler(\n                function (array $context, array $args) {\n                    return Api::createResponse(200, [\n                        'message' => 'Hello World'\n                    ]);\n                }\n            )\n        ]\n    ]\n];\n","site\u002Fconfig\u002Fconfig.php","php","",[122,234,235,252,259,268,280,286,300,313,334,354,376,387,393,399,405,411,417],{"__ignoreMap":232},[236,237,240,244,248],"span",{"class":238,"line":239},"line",1,[236,241,243],{"class":242},"s8jYJ","use",[236,245,247],{"class":246},"sBjJW"," JohannSchopplich\\Headless\\Api\\Api",[236,249,251],{"class":250},"sxrX7",";\n",[236,253,255],{"class":238,"line":254},2,[236,256,258],{"emptyLinePlaceholder":257},true,"\n",[236,260,262,265],{"class":238,"line":261},3,[236,263,264],{"class":242},"return",[236,266,267],{"class":250}," [\n",[236,269,271,275,278],{"class":238,"line":270},4,[236,272,274],{"class":273},"sIIMD","    'routes'",[236,276,277],{"class":242}," =>",[236,279,267],{"class":250},[236,281,283],{"class":238,"line":282},5,[236,284,285],{"class":250},"        [\n",[236,287,289,292,294,297],{"class":238,"line":288},6,[236,290,291],{"class":273},"            'pattern'",[236,293,277],{"class":242},[236,295,296],{"class":273}," 'api\u002Fhello'",[236,298,299],{"class":250},",\n",[236,301,303,306,308,311],{"class":238,"line":302},7,[236,304,305],{"class":273},"            'method'",[236,307,277],{"class":242},[236,309,310],{"class":273}," 'GET'",[236,312,299],{"class":250},[236,314,316,319,321,324,327,331],{"class":238,"line":315},8,[236,317,318],{"class":273},"            'action'",[236,320,277],{"class":242},[236,322,323],{"class":246}," Api",[236,325,326],{"class":242},"::",[236,328,330],{"class":329},"snPdu","createHandler",[236,332,333],{"class":250},"(\n",[236,335,337,340,343,346,349,351],{"class":238,"line":336},9,[236,338,339],{"class":242},"                function",[236,341,342],{"class":250}," (",[236,344,345],{"class":242},"array",[236,347,348],{"class":250}," $context, ",[236,350,345],{"class":242},[236,352,353],{"class":250}," $args) {\n",[236,355,357,360,362,364,367,370,373],{"class":238,"line":356},10,[236,358,359],{"class":242},"                    return",[236,361,323],{"class":246},[236,363,326],{"class":242},[236,365,366],{"class":329},"createResponse",[236,368,369],{"class":250},"(",[236,371,372],{"class":246},"200",[236,374,375],{"class":250},", [\n",[236,377,379,382,384],{"class":238,"line":378},11,[236,380,381],{"class":273},"                        'message'",[236,383,277],{"class":242},[236,385,386],{"class":273}," 'Hello World'\n",[236,388,390],{"class":238,"line":389},12,[236,391,392],{"class":250},"                    ]);\n",[236,394,396],{"class":238,"line":395},13,[236,397,398],{"class":250},"                }\n",[236,400,402],{"class":238,"line":401},14,[236,403,404],{"class":250},"            )\n",[236,406,408],{"class":238,"line":407},15,[236,409,410],{"class":250},"        ]\n",[236,412,414],{"class":238,"line":413},16,[236,415,416],{"class":250},"    ]\n",[236,418,420],{"class":238,"line":419},17,[236,421,422],{"class":250},"];\n",[214,424,426],{"id":425},"route-with-authentication","Route With Authentication",[69,428,429],{},"Protect routes using the built-in bearer token middleware:",[226,431,433],{"className":228,"code":432,"filename":230,"language":231,"meta":232,"style":232},"use JohannSchopplich\\Headless\\Api\\Api;\nuse JohannSchopplich\\Headless\\Api\\Middlewares;\n\nreturn [\n    'routes' => [\n        [\n            'pattern' => 'api\u002Fprotected',\n            'method' => 'GET',\n            'action' => Api::createHandler(\n                Middlewares::hasBearerToken(),\n                function (array $context, array $args) {\n                    return Api::createResponse(200, [\n                        'data' => 'Protected content'\n                    ]);\n                }\n            )\n        ]\n    ]\n];\n",[122,434,435,443,452,456,462,470,474,485,495,509,522,536,552,562,566,570,574,578,583],{"__ignoreMap":232},[236,436,437,439,441],{"class":238,"line":239},[236,438,243],{"class":242},[236,440,247],{"class":246},[236,442,251],{"class":250},[236,444,445,447,450],{"class":238,"line":254},[236,446,243],{"class":242},[236,448,449],{"class":246}," JohannSchopplich\\Headless\\Api\\Middlewares",[236,451,251],{"class":250},[236,453,454],{"class":238,"line":261},[236,455,258],{"emptyLinePlaceholder":257},[236,457,458,460],{"class":238,"line":270},[236,459,264],{"class":242},[236,461,267],{"class":250},[236,463,464,466,468],{"class":238,"line":282},[236,465,274],{"class":273},[236,467,277],{"class":242},[236,469,267],{"class":250},[236,471,472],{"class":238,"line":288},[236,473,285],{"class":250},[236,475,476,478,480,483],{"class":238,"line":302},[236,477,291],{"class":273},[236,479,277],{"class":242},[236,481,482],{"class":273}," 'api\u002Fprotected'",[236,484,299],{"class":250},[236,486,487,489,491,493],{"class":238,"line":315},[236,488,305],{"class":273},[236,490,277],{"class":242},[236,492,310],{"class":273},[236,494,299],{"class":250},[236,496,497,499,501,503,505,507],{"class":238,"line":336},[236,498,318],{"class":273},[236,500,277],{"class":242},[236,502,323],{"class":246},[236,504,326],{"class":242},[236,506,330],{"class":329},[236,508,333],{"class":250},[236,510,511,514,516,519],{"class":238,"line":356},[236,512,513],{"class":246},"                Middlewares",[236,515,326],{"class":242},[236,517,518],{"class":329},"hasBearerToken",[236,520,521],{"class":250},"(),\n",[236,523,524,526,528,530,532,534],{"class":238,"line":378},[236,525,339],{"class":242},[236,527,342],{"class":250},[236,529,345],{"class":242},[236,531,348],{"class":250},[236,533,345],{"class":242},[236,535,353],{"class":250},[236,537,538,540,542,544,546,548,550],{"class":238,"line":389},[236,539,359],{"class":242},[236,541,323],{"class":246},[236,543,326],{"class":242},[236,545,366],{"class":329},[236,547,369],{"class":250},[236,549,372],{"class":246},[236,551,375],{"class":250},[236,553,554,557,559],{"class":238,"line":395},[236,555,556],{"class":273},"                        'data'",[236,558,277],{"class":242},[236,560,561],{"class":273}," 'Protected content'\n",[236,563,564],{"class":238,"line":401},[236,565,392],{"class":250},[236,567,568],{"class":238,"line":407},[236,569,398],{"class":250},[236,571,572],{"class":238,"line":413},[236,573,404],{"class":250},[236,575,576],{"class":238,"line":419},[236,577,410],{"class":250},[236,579,581],{"class":238,"line":580},18,[236,582,416],{"class":250},[236,584,586],{"class":238,"line":585},19,[236,587,422],{"class":250},[214,589,591],{"id":590},"extending-kirbys-api","Extending Kirby's API",[69,593,594,595,598],{},"Add routes to Kirby's ",[122,596,597],{},"\u002Fapi"," namespace:",[600,601,602],"code-collapse",{},[226,603,605],{"className":228,"code":604,"filename":230,"language":231,"meta":232,"style":232},"use JohannSchopplich\\Headless\\Api\\Api;\nuse JohannSchopplich\\Headless\\Api\\Middlewares;\n\nreturn [\n    'api' => [\n        'routes' => [\n            [\n                'pattern' => 'posts',\n                'method' => 'GET',\n                'auth' => false, \u002F\u002F Disable Kirby's default auth\n                'action' => Api::createHandler(\n                    Middlewares::hasBearerToken(),\n                    function (array $context, array $args) {\n                        $posts = kirby()->site()->find('blog')->children();\n\n                        return Api::createResponse(200, [\n                            'posts' => $posts->map(fn ($p) => [\n                                'title' => $p->title()->value(),\n                                'uri' => $p->uri()\n                            ])->values()\n                        ]);\n                    }\n                )\n            ]\n        ]\n    ]\n];\n",[122,606,607,615,623,627,633,642,651,656,668,679,696,711,722,737,780,784,801,824,848,865,878,884,890,896,902,907,912],{"__ignoreMap":232},[236,608,609,611,613],{"class":238,"line":239},[236,610,243],{"class":242},[236,612,247],{"class":246},[236,614,251],{"class":250},[236,616,617,619,621],{"class":238,"line":254},[236,618,243],{"class":242},[236,620,449],{"class":246},[236,622,251],{"class":250},[236,624,625],{"class":238,"line":261},[236,626,258],{"emptyLinePlaceholder":257},[236,628,629,631],{"class":238,"line":270},[236,630,264],{"class":242},[236,632,267],{"class":250},[236,634,635,638,640],{"class":238,"line":282},[236,636,637],{"class":273},"    'api'",[236,639,277],{"class":242},[236,641,267],{"class":250},[236,643,644,647,649],{"class":238,"line":288},[236,645,646],{"class":273},"        'routes'",[236,648,277],{"class":242},[236,650,267],{"class":250},[236,652,653],{"class":238,"line":302},[236,654,655],{"class":250},"            [\n",[236,657,658,661,663,666],{"class":238,"line":315},[236,659,660],{"class":273},"                'pattern'",[236,662,277],{"class":242},[236,664,665],{"class":273}," 'posts'",[236,667,299],{"class":250},[236,669,670,673,675,677],{"class":238,"line":336},[236,671,672],{"class":273},"                'method'",[236,674,277],{"class":242},[236,676,310],{"class":273},[236,678,299],{"class":250},[236,680,681,684,686,689,692],{"class":238,"line":356},[236,682,683],{"class":273},"                'auth'",[236,685,277],{"class":242},[236,687,688],{"class":246}," false",[236,690,691],{"class":250},", ",[236,693,695],{"class":694},"sCsY4","\u002F\u002F Disable Kirby's default auth\n",[236,697,698,701,703,705,707,709],{"class":238,"line":378},[236,699,700],{"class":273},"                'action'",[236,702,277],{"class":242},[236,704,323],{"class":246},[236,706,326],{"class":242},[236,708,330],{"class":329},[236,710,333],{"class":250},[236,712,713,716,718,720],{"class":238,"line":389},[236,714,715],{"class":246},"                    Middlewares",[236,717,326],{"class":242},[236,719,518],{"class":329},[236,721,521],{"class":250},[236,723,724,727,729,731,733,735],{"class":238,"line":395},[236,725,726],{"class":242},"                    function",[236,728,342],{"class":250},[236,730,345],{"class":242},[236,732,348],{"class":250},[236,734,345],{"class":242},[236,736,353],{"class":250},[236,738,739,742,745,748,751,754,757,759,761,764,766,769,772,774,777],{"class":238,"line":401},[236,740,741],{"class":250},"                        $posts ",[236,743,744],{"class":242},"=",[236,746,747],{"class":329}," kirby",[236,749,750],{"class":250},"()",[236,752,753],{"class":242},"->",[236,755,756],{"class":329},"site",[236,758,750],{"class":250},[236,760,753],{"class":242},[236,762,763],{"class":329},"find",[236,765,369],{"class":250},[236,767,768],{"class":273},"'blog'",[236,770,771],{"class":250},")",[236,773,753],{"class":242},[236,775,776],{"class":329},"children",[236,778,779],{"class":250},"();\n",[236,781,782],{"class":238,"line":407},[236,783,258],{"emptyLinePlaceholder":257},[236,785,786,789,791,793,795,797,799],{"class":238,"line":413},[236,787,788],{"class":242},"                        return",[236,790,323],{"class":246},[236,792,326],{"class":242},[236,794,366],{"class":329},[236,796,369],{"class":250},[236,798,372],{"class":246},[236,800,375],{"class":250},[236,802,803,806,808,811,813,816,818,821],{"class":238,"line":419},[236,804,805],{"class":273},"                            'posts'",[236,807,277],{"class":242},[236,809,810],{"class":250}," $posts",[236,812,753],{"class":242},[236,814,815],{"class":329},"map",[236,817,369],{"class":250},[236,819,820],{"class":242},"fn",[236,822,823],{"class":250}," ($p) => [\n",[236,825,826,829,831,834,836,839,841,843,846],{"class":238,"line":580},[236,827,828],{"class":273},"                                'title'",[236,830,277],{"class":242},[236,832,833],{"class":250}," $p",[236,835,753],{"class":242},[236,837,838],{"class":329},"title",[236,840,750],{"class":250},[236,842,753],{"class":242},[236,844,845],{"class":329},"value",[236,847,521],{"class":250},[236,849,850,853,855,857,859,862],{"class":238,"line":585},[236,851,852],{"class":273},"                                'uri'",[236,854,277],{"class":242},[236,856,833],{"class":250},[236,858,753],{"class":242},[236,860,861],{"class":329},"uri",[236,863,864],{"class":250},"()\n",[236,866,868,871,873,876],{"class":238,"line":867},20,[236,869,870],{"class":250},"                            ])",[236,872,753],{"class":242},[236,874,875],{"class":329},"values",[236,877,864],{"class":250},[236,879,881],{"class":238,"line":880},21,[236,882,883],{"class":250},"                        ]);\n",[236,885,887],{"class":238,"line":886},22,[236,888,889],{"class":250},"                    }\n",[236,891,893],{"class":238,"line":892},23,[236,894,895],{"class":250},"                )\n",[236,897,899],{"class":238,"line":898},24,[236,900,901],{"class":250},"            ]\n",[236,903,905],{"class":238,"line":904},25,[236,906,410],{"class":250},[236,908,910],{"class":238,"line":909},26,[236,911,416],{"class":250},[236,913,915],{"class":238,"line":914},27,[236,916,422],{"class":250},[114,918,920],{"id":919},"built-in-middlewares","Built-in Middlewares",[69,922,923,924,927],{},"Kirby Headless provides several built-in middleware functions in the ",[122,925,926],{},"Middlewares"," class:",[929,930,931],"warning",{},[69,932,933,934,937],{},"Order matters: ",[122,935,936],{},"hasBearerToken()"," has to come first in your chain – otherwise a resolver hands out its result before the token is ever checked.",[214,939,941],{"id":940},"hasbearertoken",[122,942,936],{},[69,944,945,946,949,950,953,954,957,958,224],{},"Validates the bearer token against the configured ",[122,947,948],{},"headless.token",". It does not redirect by default; pass ",[122,951,952],{},"hasBearerToken(true)"," to redirect browser navigations to the Panel when ",[122,955,956],{},"headless.panel.redirect"," is enabled, as described under ",[76,959,961],{"href":960},"\u002Fdocs\u002Fheadless\u002Fconfiguration\u002Fpanel#panel-redirect","Panel Redirect",[226,963,965],{"className":228,"code":964,"language":231,"meta":232,"style":232},"use JohannSchopplich\\Headless\\Api\\Middlewares;\n\nApi::createHandler(\n    Middlewares::hasBearerToken(),\n    function (array $context, array $args) {\n        \u002F\u002F Token is valid\n    }\n);\n",[122,966,967,975,979,990,1001,1016,1021,1026],{"__ignoreMap":232},[236,968,969,971,973],{"class":238,"line":239},[236,970,243],{"class":242},[236,972,449],{"class":246},[236,974,251],{"class":250},[236,976,977],{"class":238,"line":254},[236,978,258],{"emptyLinePlaceholder":257},[236,980,981,984,986,988],{"class":238,"line":261},[236,982,983],{"class":246},"Api",[236,985,326],{"class":242},[236,987,330],{"class":329},[236,989,333],{"class":250},[236,991,992,995,997,999],{"class":238,"line":270},[236,993,994],{"class":246},"    Middlewares",[236,996,326],{"class":242},[236,998,518],{"class":329},[236,1000,521],{"class":250},[236,1002,1003,1006,1008,1010,1012,1014],{"class":238,"line":282},[236,1004,1005],{"class":242},"    function",[236,1007,342],{"class":250},[236,1009,345],{"class":242},[236,1011,348],{"class":250},[236,1013,345],{"class":242},[236,1015,353],{"class":250},[236,1017,1018],{"class":238,"line":288},[236,1019,1020],{"class":694},"        \u002F\u002F Token is valid\n",[236,1022,1023],{"class":238,"line":302},[236,1024,1025],{"class":250},"    }\n",[236,1027,1028],{"class":238,"line":315},[236,1029,1030],{"class":250},");\n",[214,1032,1034],{"id":1033},"applylanguageheader",[122,1035,1036],{},"applyLanguageHeader()",[69,1038,1039,1040,1043,1044,1047,1048,1050,1051,1054,1055,1057],{},"Sets the current language and translation from the ",[122,1041,1042],{},"X-Language"," header, so ",[122,1045,1046],{},"t()"," in a template speaks the language its content is in. A language prefix in the path wins over the header, and a code that matches no language of the site is ignored. Place it after ",[122,1049,936],{}," and before the resolvers. The route below rebuilds the catch-all that ",[122,1052,1053],{},"globalRoutes"," registers, for a config with ",[122,1056,1053],{}," off:",[226,1059,1061],{"className":228,"code":1060,"filename":230,"language":231,"meta":232,"style":232},"use JohannSchopplich\\Headless\\Api\\Api;\nuse JohannSchopplich\\Headless\\Api\\Middlewares;\n\nreturn [\n    'routes' => [\n        [\n            'pattern' => '(:all)',\n            'method' => 'ALL',\n            'language' => '*',\n            'action' => Api::createHandler(\n                Middlewares::hasBearerToken(true),\n                Middlewares::applyLanguageHeader(...),\n                Middlewares::tryResolveFiles(...),\n                Middlewares::tryResolvePage(...)\n            )\n        ]\n    ]\n];\n",[122,1062,1063,1071,1079,1083,1089,1097,1101,1112,1123,1135,1149,1165,1181,1196,1212,1216,1220,1224],{"__ignoreMap":232},[236,1064,1065,1067,1069],{"class":238,"line":239},[236,1066,243],{"class":242},[236,1068,247],{"class":246},[236,1070,251],{"class":250},[236,1072,1073,1075,1077],{"class":238,"line":254},[236,1074,243],{"class":242},[236,1076,449],{"class":246},[236,1078,251],{"class":250},[236,1080,1081],{"class":238,"line":261},[236,1082,258],{"emptyLinePlaceholder":257},[236,1084,1085,1087],{"class":238,"line":270},[236,1086,264],{"class":242},[236,1088,267],{"class":250},[236,1090,1091,1093,1095],{"class":238,"line":282},[236,1092,274],{"class":273},[236,1094,277],{"class":242},[236,1096,267],{"class":250},[236,1098,1099],{"class":238,"line":288},[236,1100,285],{"class":250},[236,1102,1103,1105,1107,1110],{"class":238,"line":302},[236,1104,291],{"class":273},[236,1106,277],{"class":242},[236,1108,1109],{"class":273}," '(:all)'",[236,1111,299],{"class":250},[236,1113,1114,1116,1118,1121],{"class":238,"line":315},[236,1115,305],{"class":273},[236,1117,277],{"class":242},[236,1119,1120],{"class":273}," 'ALL'",[236,1122,299],{"class":250},[236,1124,1125,1128,1130,1133],{"class":238,"line":336},[236,1126,1127],{"class":273},"            'language'",[236,1129,277],{"class":242},[236,1131,1132],{"class":273}," '*'",[236,1134,299],{"class":250},[236,1136,1137,1139,1141,1143,1145,1147],{"class":238,"line":356},[236,1138,318],{"class":273},[236,1140,277],{"class":242},[236,1142,323],{"class":246},[236,1144,326],{"class":242},[236,1146,330],{"class":329},[236,1148,333],{"class":250},[236,1150,1151,1153,1155,1157,1159,1162],{"class":238,"line":378},[236,1152,513],{"class":246},[236,1154,326],{"class":242},[236,1156,518],{"class":329},[236,1158,369],{"class":250},[236,1160,1161],{"class":246},"true",[236,1163,1164],{"class":250},"),\n",[236,1166,1167,1169,1171,1174,1176,1179],{"class":238,"line":389},[236,1168,513],{"class":246},[236,1170,326],{"class":242},[236,1172,1173],{"class":329},"applyLanguageHeader",[236,1175,369],{"class":250},[236,1177,1178],{"class":242},"...",[236,1180,1164],{"class":250},[236,1182,1183,1185,1187,1190,1192,1194],{"class":238,"line":395},[236,1184,513],{"class":246},[236,1186,326],{"class":242},[236,1188,1189],{"class":329},"tryResolveFiles",[236,1191,369],{"class":250},[236,1193,1178],{"class":242},[236,1195,1164],{"class":250},[236,1197,1198,1200,1202,1205,1207,1209],{"class":238,"line":401},[236,1199,513],{"class":246},[236,1201,326],{"class":242},[236,1203,1204],{"class":329},"tryResolvePage",[236,1206,369],{"class":250},[236,1208,1178],{"class":242},[236,1210,1211],{"class":250},")\n",[236,1213,1214],{"class":238,"line":407},[236,1215,404],{"class":250},[236,1217,1218],{"class":238,"line":413},[236,1219,410],{"class":250},[236,1221,1222],{"class":238,"line":419},[236,1223,416],{"class":250},[236,1225,1226],{"class":238,"line":580},[236,1227,422],{"class":250},[69,1229,1230,1231,691,1233,1236,1237,1240,1241,1244],{},"On multi-language sites, ",[122,1232,1036],{},[122,1234,1235],{},"tryResolveFiles()",", and ",[122,1238,1239],{},"tryResolvePage()"," need this route shape: without ",[122,1242,1243],{},"'language' => '*'",", every path resolves to the home page.",[214,1246,1248],{"id":1247},"tryresolvefiles",[122,1249,1235],{},[69,1251,1252],{},"Attempts to resolve page and site files from the request path the way Kirby's own resolver does:",[1254,1255,1256,1260,1263],"ul",{},[1257,1258,1259],"li",{},"A page wins whenever its ID matches the path without its extension.",[1257,1261,1262],{},"Site files are only addressable at the root level.",[1257,1264,1265,1266,1269],{},"Every match is filtered through Kirby's ",[122,1267,1268],{},"content.fileRedirects"," option, which is disabled by default.",[226,1271,1273],{"className":228,"code":1272,"language":231,"meta":232,"style":232},"use JohannSchopplich\\Headless\\Api\\Middlewares;\n\nApi::createHandler(\n    Middlewares::hasBearerToken(),\n    Middlewares::tryResolveFiles(...),\n    function (array $context, array $args) {\n        \u002F\u002F File resolution attempted\n    }\n);\n",[122,1274,1275,1283,1287,1297,1307,1321,1335,1340,1344],{"__ignoreMap":232},[236,1276,1277,1279,1281],{"class":238,"line":239},[236,1278,243],{"class":242},[236,1280,449],{"class":246},[236,1282,251],{"class":250},[236,1284,1285],{"class":238,"line":254},[236,1286,258],{"emptyLinePlaceholder":257},[236,1288,1289,1291,1293,1295],{"class":238,"line":261},[236,1290,983],{"class":246},[236,1292,326],{"class":242},[236,1294,330],{"class":329},[236,1296,333],{"class":250},[236,1298,1299,1301,1303,1305],{"class":238,"line":270},[236,1300,994],{"class":246},[236,1302,326],{"class":242},[236,1304,518],{"class":329},[236,1306,521],{"class":250},[236,1308,1309,1311,1313,1315,1317,1319],{"class":238,"line":282},[236,1310,994],{"class":246},[236,1312,326],{"class":242},[236,1314,1189],{"class":329},[236,1316,369],{"class":250},[236,1318,1178],{"class":242},[236,1320,1164],{"class":250},[236,1322,1323,1325,1327,1329,1331,1333],{"class":238,"line":288},[236,1324,1005],{"class":242},[236,1326,342],{"class":250},[236,1328,345],{"class":242},[236,1330,348],{"class":250},[236,1332,345],{"class":242},[236,1334,353],{"class":250},[236,1336,1337],{"class":238,"line":302},[236,1338,1339],{"class":694},"        \u002F\u002F File resolution attempted\n",[236,1341,1342],{"class":238,"line":315},[236,1343,1025],{"class":250},[236,1345,1346],{"class":238,"line":336},[236,1347,1030],{"class":250},[214,1349,1351],{"id":1350},"hasbody",[122,1352,1353],{},"hasBody()",[69,1355,1356,1357,1360,1361,1364,1365,1372,1373,1376,1377,1379],{},"Answers ",[122,1358,1359],{},"400"," with ",[122,1362,1363],{},"{\"error\": \"Missing request body\"}"," when the request carries no parsed body, and otherwise puts Kirby's ",[76,1366,1369],{"href":1367,"rel":1368},"https:\u002F\u002Fgetkirby.com\u002Fdocs\u002Freference\u002Fobjects\u002Fhttp\u002Frequest\u002Fbody",[80],[122,1370,1371],{},"Body"," object into ",[122,1374,1375],{},"$context['body']"," for the middlewares that follow. Like the resolvers it is a plain middleware, so pass it as a first-class callable; only ",[122,1378,936],{}," is called:",[226,1381,1383],{"className":228,"code":1382,"language":231,"meta":232,"style":232},"use JohannSchopplich\\Headless\\Api\\Middlewares;\n\nApi::createHandler(\n    Middlewares::hasBearerToken(),\n    Middlewares::hasBody(...),\n    function (array $context, array $args) {\n        $data = $context['body']->data();\n    }\n);\n",[122,1384,1385,1393,1397,1407,1417,1432,1446,1469,1473],{"__ignoreMap":232},[236,1386,1387,1389,1391],{"class":238,"line":239},[236,1388,243],{"class":242},[236,1390,449],{"class":246},[236,1392,251],{"class":250},[236,1394,1395],{"class":238,"line":254},[236,1396,258],{"emptyLinePlaceholder":257},[236,1398,1399,1401,1403,1405],{"class":238,"line":261},[236,1400,983],{"class":246},[236,1402,326],{"class":242},[236,1404,330],{"class":329},[236,1406,333],{"class":250},[236,1408,1409,1411,1413,1415],{"class":238,"line":270},[236,1410,994],{"class":246},[236,1412,326],{"class":242},[236,1414,518],{"class":329},[236,1416,521],{"class":250},[236,1418,1419,1421,1423,1426,1428,1430],{"class":238,"line":282},[236,1420,994],{"class":246},[236,1422,326],{"class":242},[236,1424,1425],{"class":329},"hasBody",[236,1427,369],{"class":250},[236,1429,1178],{"class":242},[236,1431,1164],{"class":250},[236,1433,1434,1436,1438,1440,1442,1444],{"class":238,"line":288},[236,1435,1005],{"class":242},[236,1437,342],{"class":250},[236,1439,345],{"class":242},[236,1441,348],{"class":250},[236,1443,345],{"class":242},[236,1445,353],{"class":250},[236,1447,1448,1451,1453,1456,1459,1462,1464,1467],{"class":238,"line":302},[236,1449,1450],{"class":250},"        $data ",[236,1452,744],{"class":242},[236,1454,1455],{"class":250}," $context[",[236,1457,1458],{"class":273},"'body'",[236,1460,1461],{"class":250},"]",[236,1463,753],{"class":242},[236,1465,1466],{"class":329},"data",[236,1468,779],{"class":250},[236,1470,1471],{"class":238,"line":315},[236,1472,1025],{"class":250},[236,1474,1475],{"class":238,"line":336},[236,1476,1030],{"class":250},[214,1478,1480],{"id":1479},"tryresolvepage",[122,1481,1239],{},[69,1483,1484,1485,1488,1489,1492,1493,1496,1497,1499],{},"Attempts to resolve page requests, honoring the content representation Kirby would serve for the path's extension: the extensionless path and ",[122,1486,1487],{},".json"," return page JSON, ",[122,1490,1491],{},".html"," redirects to the canonical page URL, and any other extension needs a matching ",[122,1494,1495],{},"*.php"," representation. Drafts resolve for a logged-in Panel user or a valid preview token. The answer is Kirby's response object, so the template's own status code and headers are part of it. Returns ",[122,1498,167],{}," when the path carries another language's URL prefix, unless the current language resolves the full path to a page of its own:",[226,1501,1503],{"className":228,"code":1502,"language":231,"meta":232,"style":232},"use JohannSchopplich\\Headless\\Api\\Middlewares;\n\nApi::createHandler(\n    Middlewares::hasBearerToken(),\n    Middlewares::tryResolvePage(...),\n    function (array $context, array $args) {\n        \u002F\u002F Page resolution attempted\n    }\n);\n",[122,1504,1505,1513,1517,1527,1537,1551,1565,1570,1574],{"__ignoreMap":232},[236,1506,1507,1509,1511],{"class":238,"line":239},[236,1508,243],{"class":242},[236,1510,449],{"class":246},[236,1512,251],{"class":250},[236,1514,1515],{"class":238,"line":254},[236,1516,258],{"emptyLinePlaceholder":257},[236,1518,1519,1521,1523,1525],{"class":238,"line":261},[236,1520,983],{"class":246},[236,1522,326],{"class":242},[236,1524,330],{"class":329},[236,1526,333],{"class":250},[236,1528,1529,1531,1533,1535],{"class":238,"line":270},[236,1530,994],{"class":246},[236,1532,326],{"class":242},[236,1534,518],{"class":329},[236,1536,521],{"class":250},[236,1538,1539,1541,1543,1545,1547,1549],{"class":238,"line":282},[236,1540,994],{"class":246},[236,1542,326],{"class":242},[236,1544,1204],{"class":329},[236,1546,369],{"class":250},[236,1548,1178],{"class":242},[236,1550,1164],{"class":250},[236,1552,1553,1555,1557,1559,1561,1563],{"class":238,"line":288},[236,1554,1005],{"class":242},[236,1556,342],{"class":250},[236,1558,345],{"class":242},[236,1560,348],{"class":250},[236,1562,345],{"class":242},[236,1564,353],{"class":250},[236,1566,1567],{"class":238,"line":302},[236,1568,1569],{"class":694},"        \u002F\u002F Page resolution attempted\n",[236,1571,1572],{"class":238,"line":315},[236,1573,1025],{"class":250},[236,1575,1576],{"class":238,"line":336},[236,1577,1030],{"class":250},[114,1579,1581],{"id":1580},"custom-middleware","Custom Middleware",[69,1583,1584],{},"Create custom middleware functions to handle validation, data transformation, or other logic:",[600,1586,1587],{},[226,1588,1590],{"className":228,"code":1589,"filename":230,"language":231,"meta":232,"style":232},"use JohannSchopplich\\Headless\\Api\\Api;\n\n\u002F\u002F Define custom middleware\n$requireDateParam = function (array $context, array $args) {\n    $date = kirby()->request()->get('date');\n\n    if (empty($date)) {\n        return Api::createResponse(400, [\n            'error' => 'Missing date parameter'\n        ]);\n    }\n\n    \u002F\u002F Add date to context for use in later handlers\n    $context['date'] = $date;\n    return $context;\n};\n\nreturn [\n    'routes' => [\n        [\n            'pattern' => 'api\u002Fevents',\n            'method' => 'GET',\n            'action' => Api::createHandler(\n                $requireDateParam,\n                function (array $context, array $args) {\n                    $date = $context['date'];\n\n                    return Api::createResponse(200, [\n                        'date' => $date,\n                        'events' => [] \u002F\u002F Your event data\n                    ]);\n                }\n            )\n        ]\n    ]\n];\n",[122,1591,1592,1600,1604,1609,1629,1659,1663,1676,1693,1703,1708,1712,1716,1721,1736,1744,1749,1753,1759,1767,1771,1782,1792,1806,1811,1825,1838,1842,1859,1870,1884,1889,1894,1899,1904,1909],{"__ignoreMap":232},[236,1593,1594,1596,1598],{"class":238,"line":239},[236,1595,243],{"class":242},[236,1597,247],{"class":246},[236,1599,251],{"class":250},[236,1601,1602],{"class":238,"line":254},[236,1603,258],{"emptyLinePlaceholder":257},[236,1605,1606],{"class":238,"line":261},[236,1607,1608],{"class":694},"\u002F\u002F Define custom middleware\n",[236,1610,1611,1614,1616,1619,1621,1623,1625,1627],{"class":238,"line":270},[236,1612,1613],{"class":250},"$requireDateParam ",[236,1615,744],{"class":242},[236,1617,1618],{"class":242}," function",[236,1620,342],{"class":250},[236,1622,345],{"class":242},[236,1624,348],{"class":250},[236,1626,345],{"class":242},[236,1628,353],{"class":250},[236,1630,1631,1634,1636,1638,1640,1642,1645,1647,1649,1652,1654,1657],{"class":238,"line":282},[236,1632,1633],{"class":250},"    $date ",[236,1635,744],{"class":242},[236,1637,747],{"class":329},[236,1639,750],{"class":250},[236,1641,753],{"class":242},[236,1643,1644],{"class":329},"request",[236,1646,750],{"class":250},[236,1648,753],{"class":242},[236,1650,1651],{"class":329},"get",[236,1653,369],{"class":250},[236,1655,1656],{"class":273},"'date'",[236,1658,1030],{"class":250},[236,1660,1661],{"class":238,"line":288},[236,1662,258],{"emptyLinePlaceholder":257},[236,1664,1665,1668,1670,1673],{"class":238,"line":302},[236,1666,1667],{"class":242},"    if",[236,1669,342],{"class":250},[236,1671,1672],{"class":246},"empty",[236,1674,1675],{"class":250},"($date)) {\n",[236,1677,1678,1681,1683,1685,1687,1689,1691],{"class":238,"line":315},[236,1679,1680],{"class":242},"        return",[236,1682,323],{"class":246},[236,1684,326],{"class":242},[236,1686,366],{"class":329},[236,1688,369],{"class":250},[236,1690,1359],{"class":246},[236,1692,375],{"class":250},[236,1694,1695,1698,1700],{"class":238,"line":336},[236,1696,1697],{"class":273},"            'error'",[236,1699,277],{"class":242},[236,1701,1702],{"class":273}," 'Missing date parameter'\n",[236,1704,1705],{"class":238,"line":356},[236,1706,1707],{"class":250},"        ]);\n",[236,1709,1710],{"class":238,"line":378},[236,1711,1025],{"class":250},[236,1713,1714],{"class":238,"line":389},[236,1715,258],{"emptyLinePlaceholder":257},[236,1717,1718],{"class":238,"line":395},[236,1719,1720],{"class":694},"    \u002F\u002F Add date to context for use in later handlers\n",[236,1722,1723,1726,1728,1731,1733],{"class":238,"line":401},[236,1724,1725],{"class":250},"    $context[",[236,1727,1656],{"class":273},[236,1729,1730],{"class":250},"] ",[236,1732,744],{"class":242},[236,1734,1735],{"class":250}," $date;\n",[236,1737,1738,1741],{"class":238,"line":407},[236,1739,1740],{"class":242},"    return",[236,1742,1743],{"class":250}," $context;\n",[236,1745,1746],{"class":238,"line":413},[236,1747,1748],{"class":250},"};\n",[236,1750,1751],{"class":238,"line":419},[236,1752,258],{"emptyLinePlaceholder":257},[236,1754,1755,1757],{"class":238,"line":580},[236,1756,264],{"class":242},[236,1758,267],{"class":250},[236,1760,1761,1763,1765],{"class":238,"line":585},[236,1762,274],{"class":273},[236,1764,277],{"class":242},[236,1766,267],{"class":250},[236,1768,1769],{"class":238,"line":867},[236,1770,285],{"class":250},[236,1772,1773,1775,1777,1780],{"class":238,"line":880},[236,1774,291],{"class":273},[236,1776,277],{"class":242},[236,1778,1779],{"class":273}," 'api\u002Fevents'",[236,1781,299],{"class":250},[236,1783,1784,1786,1788,1790],{"class":238,"line":886},[236,1785,305],{"class":273},[236,1787,277],{"class":242},[236,1789,310],{"class":273},[236,1791,299],{"class":250},[236,1793,1794,1796,1798,1800,1802,1804],{"class":238,"line":892},[236,1795,318],{"class":273},[236,1797,277],{"class":242},[236,1799,323],{"class":246},[236,1801,326],{"class":242},[236,1803,330],{"class":329},[236,1805,333],{"class":250},[236,1807,1808],{"class":238,"line":898},[236,1809,1810],{"class":250},"                $requireDateParam,\n",[236,1812,1813,1815,1817,1819,1821,1823],{"class":238,"line":904},[236,1814,339],{"class":242},[236,1816,342],{"class":250},[236,1818,345],{"class":242},[236,1820,348],{"class":250},[236,1822,345],{"class":242},[236,1824,353],{"class":250},[236,1826,1827,1830,1832,1834,1836],{"class":238,"line":909},[236,1828,1829],{"class":250},"                    $date ",[236,1831,744],{"class":242},[236,1833,1455],{"class":250},[236,1835,1656],{"class":273},[236,1837,422],{"class":250},[236,1839,1840],{"class":238,"line":914},[236,1841,258],{"emptyLinePlaceholder":257},[236,1843,1845,1847,1849,1851,1853,1855,1857],{"class":238,"line":1844},28,[236,1846,359],{"class":242},[236,1848,323],{"class":246},[236,1850,326],{"class":242},[236,1852,366],{"class":329},[236,1854,369],{"class":250},[236,1856,372],{"class":246},[236,1858,375],{"class":250},[236,1860,1862,1865,1867],{"class":238,"line":1861},29,[236,1863,1864],{"class":273},"                        'date'",[236,1866,277],{"class":242},[236,1868,1869],{"class":250}," $date,\n",[236,1871,1873,1876,1878,1881],{"class":238,"line":1872},30,[236,1874,1875],{"class":273},"                        'events'",[236,1877,277],{"class":242},[236,1879,1880],{"class":250}," [] ",[236,1882,1883],{"class":694},"\u002F\u002F Your event data\n",[236,1885,1887],{"class":238,"line":1886},31,[236,1888,392],{"class":250},[236,1890,1892],{"class":238,"line":1891},32,[236,1893,398],{"class":250},[236,1895,1897],{"class":238,"line":1896},33,[236,1898,404],{"class":250},[236,1900,1902],{"class":238,"line":1901},34,[236,1903,410],{"class":250},[236,1905,1907],{"class":238,"line":1906},35,[236,1908,416],{"class":250},[236,1910,1912],{"class":238,"line":1911},36,[236,1913,422],{"class":250},[114,1915,1917],{"id":1916},"response-format","Response Format",[69,1919,1920,1923,1924,224],{},[122,1921,1922],{},"Api::createResponse(int $code, mixed $data = null, array $headers = [])"," answers with a JSON envelope that carries the status code and, when you pass data, a ",[122,1925,1926],{},"result",[226,1928,1932],{"className":1929,"code":1930,"language":1931,"meta":232,"style":232},"language-json shiki shiki-themes github-light github-light github-dark","{\n  \"code\": 200,\n  \"status\": \"OK\",\n  \"result\": {\n    \"message\": \"Success\"\n  }\n}\n","json",[122,1933,1934,1939,1951,1963,1971,1981,1986],{"__ignoreMap":232},[236,1935,1936],{"class":238,"line":239},[236,1937,1938],{"class":250},"{\n",[236,1940,1941,1944,1947,1949],{"class":238,"line":254},[236,1942,1943],{"class":246},"  \"code\"",[236,1945,1946],{"class":250},": ",[236,1948,372],{"class":246},[236,1950,299],{"class":250},[236,1952,1953,1956,1958,1961],{"class":238,"line":261},[236,1954,1955],{"class":246},"  \"status\"",[236,1957,1946],{"class":250},[236,1959,1960],{"class":273},"\"OK\"",[236,1962,299],{"class":250},[236,1964,1965,1968],{"class":238,"line":270},[236,1966,1967],{"class":246},"  \"result\"",[236,1969,1970],{"class":250},": {\n",[236,1972,1973,1976,1978],{"class":238,"line":282},[236,1974,1975],{"class":246},"    \"message\"",[236,1977,1946],{"class":250},[236,1979,1980],{"class":273},"\"Success\"\n",[236,1982,1983],{"class":238,"line":288},[236,1984,1985],{"class":250},"  }\n",[236,1987,1988],{"class":238,"line":302},[236,1989,1990],{"class":250},"}\n",[69,1992,1993],{},"Error responses follow the same pattern:",[226,1995,1997],{"className":1929,"code":1996,"language":1931,"meta":232,"style":232},"{\n  \"code\": 401,\n  \"status\": \"Unauthorized\"\n}\n",[122,1998,1999,2003,2014,2023],{"__ignoreMap":232},[236,2000,2001],{"class":238,"line":239},[236,2002,1938],{"class":250},[236,2004,2005,2007,2009,2012],{"class":238,"line":254},[236,2006,1943],{"class":246},[236,2008,1946],{"class":250},[236,2010,2011],{"class":246},"401",[236,2013,299],{"class":250},[236,2015,2016,2018,2020],{"class":238,"line":261},[236,2017,1955],{"class":246},[236,2019,1946],{"class":250},[236,2021,2022],{"class":273},"\"Unauthorized\"\n",[236,2024,2025],{"class":238,"line":270},[236,2026,1990],{"class":250},[69,2028,2029,2032,2033,691,2036,2039,2040,2043],{},[122,2030,2031],{},"status"," is Kirby's message for the code, or the name of its class – ",[122,2034,2035],{},"Client Error",[122,2037,2038],{},"Server Error"," – where Kirby lists none. ",[122,2041,2042],{},"$headers"," adds headers to the response.",[114,2045,2047],{"id":2046},"examples","Examples",[214,2049,2051],{"id":2050},"post-endpoint-with-validation","POST Endpoint With Validation",[600,2053,2054],{},[226,2055,2057],{"className":228,"code":2056,"filename":230,"language":231,"meta":232,"style":232},"use JohannSchopplich\\Headless\\Api\\Api;\nuse JohannSchopplich\\Headless\\Api\\Middlewares;\n\n$requireTitle = function (array $context, array $args) {\n    $data = $context['body']->data();\n\n    if (empty($data['title'])) {\n        return Api::createResponse(400, [\n            'error' => 'Title is required'\n        ]);\n    }\n\n    $context['data'] = $data;\n    return $context;\n};\n\nreturn [\n    'routes' => [\n        [\n            'pattern' => 'api\u002Fpages',\n            'method' => 'POST',\n            'action' => Api::createHandler(\n                Middlewares::hasBearerToken(),\n                Middlewares::hasBody(...),\n                $requireTitle,\n                function (array $context, array $args) {\n                    $data = $context['data'];\n\n                    \u002F\u002F Create page logic here\n\n                    return Api::createResponse(201, [\n                        'message' => 'Page created'\n                    ]);\n                }\n            )\n        ]\n    ]\n];\n",[122,2058,2059,2067,2075,2079,2098,2117,2121,2138,2154,2163,2167,2171,2175,2189,2195,2199,2203,2209,2217,2221,2232,2243,2257,2267,2281,2286,2300,2313,2317,2322,2326,2343,2352,2356,2360,2364,2368,2373],{"__ignoreMap":232},[236,2060,2061,2063,2065],{"class":238,"line":239},[236,2062,243],{"class":242},[236,2064,247],{"class":246},[236,2066,251],{"class":250},[236,2068,2069,2071,2073],{"class":238,"line":254},[236,2070,243],{"class":242},[236,2072,449],{"class":246},[236,2074,251],{"class":250},[236,2076,2077],{"class":238,"line":261},[236,2078,258],{"emptyLinePlaceholder":257},[236,2080,2081,2084,2086,2088,2090,2092,2094,2096],{"class":238,"line":270},[236,2082,2083],{"class":250},"$requireTitle ",[236,2085,744],{"class":242},[236,2087,1618],{"class":242},[236,2089,342],{"class":250},[236,2091,345],{"class":242},[236,2093,348],{"class":250},[236,2095,345],{"class":242},[236,2097,353],{"class":250},[236,2099,2100,2103,2105,2107,2109,2111,2113,2115],{"class":238,"line":282},[236,2101,2102],{"class":250},"    $data ",[236,2104,744],{"class":242},[236,2106,1455],{"class":250},[236,2108,1458],{"class":273},[236,2110,1461],{"class":250},[236,2112,753],{"class":242},[236,2114,1466],{"class":329},[236,2116,779],{"class":250},[236,2118,2119],{"class":238,"line":288},[236,2120,258],{"emptyLinePlaceholder":257},[236,2122,2123,2125,2127,2129,2132,2135],{"class":238,"line":302},[236,2124,1667],{"class":242},[236,2126,342],{"class":250},[236,2128,1672],{"class":246},[236,2130,2131],{"class":250},"($data[",[236,2133,2134],{"class":273},"'title'",[236,2136,2137],{"class":250},"])) {\n",[236,2139,2140,2142,2144,2146,2148,2150,2152],{"class":238,"line":315},[236,2141,1680],{"class":242},[236,2143,323],{"class":246},[236,2145,326],{"class":242},[236,2147,366],{"class":329},[236,2149,369],{"class":250},[236,2151,1359],{"class":246},[236,2153,375],{"class":250},[236,2155,2156,2158,2160],{"class":238,"line":336},[236,2157,1697],{"class":273},[236,2159,277],{"class":242},[236,2161,2162],{"class":273}," 'Title is required'\n",[236,2164,2165],{"class":238,"line":356},[236,2166,1707],{"class":250},[236,2168,2169],{"class":238,"line":378},[236,2170,1025],{"class":250},[236,2172,2173],{"class":238,"line":389},[236,2174,258],{"emptyLinePlaceholder":257},[236,2176,2177,2179,2182,2184,2186],{"class":238,"line":395},[236,2178,1725],{"class":250},[236,2180,2181],{"class":273},"'data'",[236,2183,1730],{"class":250},[236,2185,744],{"class":242},[236,2187,2188],{"class":250}," $data;\n",[236,2190,2191,2193],{"class":238,"line":401},[236,2192,1740],{"class":242},[236,2194,1743],{"class":250},[236,2196,2197],{"class":238,"line":407},[236,2198,1748],{"class":250},[236,2200,2201],{"class":238,"line":413},[236,2202,258],{"emptyLinePlaceholder":257},[236,2204,2205,2207],{"class":238,"line":419},[236,2206,264],{"class":242},[236,2208,267],{"class":250},[236,2210,2211,2213,2215],{"class":238,"line":580},[236,2212,274],{"class":273},[236,2214,277],{"class":242},[236,2216,267],{"class":250},[236,2218,2219],{"class":238,"line":585},[236,2220,285],{"class":250},[236,2222,2223,2225,2227,2230],{"class":238,"line":867},[236,2224,291],{"class":273},[236,2226,277],{"class":242},[236,2228,2229],{"class":273}," 'api\u002Fpages'",[236,2231,299],{"class":250},[236,2233,2234,2236,2238,2241],{"class":238,"line":880},[236,2235,305],{"class":273},[236,2237,277],{"class":242},[236,2239,2240],{"class":273}," 'POST'",[236,2242,299],{"class":250},[236,2244,2245,2247,2249,2251,2253,2255],{"class":238,"line":886},[236,2246,318],{"class":273},[236,2248,277],{"class":242},[236,2250,323],{"class":246},[236,2252,326],{"class":242},[236,2254,330],{"class":329},[236,2256,333],{"class":250},[236,2258,2259,2261,2263,2265],{"class":238,"line":892},[236,2260,513],{"class":246},[236,2262,326],{"class":242},[236,2264,518],{"class":329},[236,2266,521],{"class":250},[236,2268,2269,2271,2273,2275,2277,2279],{"class":238,"line":898},[236,2270,513],{"class":246},[236,2272,326],{"class":242},[236,2274,1425],{"class":329},[236,2276,369],{"class":250},[236,2278,1178],{"class":242},[236,2280,1164],{"class":250},[236,2282,2283],{"class":238,"line":904},[236,2284,2285],{"class":250},"                $requireTitle,\n",[236,2287,2288,2290,2292,2294,2296,2298],{"class":238,"line":909},[236,2289,339],{"class":242},[236,2291,342],{"class":250},[236,2293,345],{"class":242},[236,2295,348],{"class":250},[236,2297,345],{"class":242},[236,2299,353],{"class":250},[236,2301,2302,2305,2307,2309,2311],{"class":238,"line":914},[236,2303,2304],{"class":250},"                    $data ",[236,2306,744],{"class":242},[236,2308,1455],{"class":250},[236,2310,2181],{"class":273},[236,2312,422],{"class":250},[236,2314,2315],{"class":238,"line":1844},[236,2316,258],{"emptyLinePlaceholder":257},[236,2318,2319],{"class":238,"line":1861},[236,2320,2321],{"class":694},"                    \u002F\u002F Create page logic here\n",[236,2323,2324],{"class":238,"line":1872},[236,2325,258],{"emptyLinePlaceholder":257},[236,2327,2328,2330,2332,2334,2336,2338,2341],{"class":238,"line":1886},[236,2329,359],{"class":242},[236,2331,323],{"class":246},[236,2333,326],{"class":242},[236,2335,366],{"class":329},[236,2337,369],{"class":250},[236,2339,2340],{"class":246},"201",[236,2342,375],{"class":250},[236,2344,2345,2347,2349],{"class":238,"line":1891},[236,2346,381],{"class":273},[236,2348,277],{"class":242},[236,2350,2351],{"class":273}," 'Page created'\n",[236,2353,2354],{"class":238,"line":1896},[236,2355,392],{"class":250},[236,2357,2358],{"class":238,"line":1901},[236,2359,398],{"class":250},[236,2361,2362],{"class":238,"line":1906},[236,2363,404],{"class":250},[236,2365,2366],{"class":238,"line":1911},[236,2367,410],{"class":250},[236,2369,2371],{"class":238,"line":2370},37,[236,2372,416],{"class":250},[236,2374,2376],{"class":238,"line":2375},38,[236,2377,422],{"class":250},[2379,2380,2381],"style",{},"html pre.shiki code .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sIIMD, html code.shiki .sIIMD{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .snPdu, html code.shiki .snPdu{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0}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 .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":232,"searchDepth":254,"depth":254,"links":2383},[2384,2385,2390,2397,2398,2399],{"id":116,"depth":254,"text":117},{"id":211,"depth":254,"text":212,"children":2386},[2387,2388,2389],{"id":216,"depth":261,"text":217},{"id":425,"depth":261,"text":426},{"id":590,"depth":261,"text":591},{"id":919,"depth":254,"text":920,"children":2391},[2392,2393,2394,2395,2396],{"id":940,"depth":261,"text":936},{"id":1033,"depth":261,"text":1036},{"id":1247,"depth":261,"text":1235},{"id":1350,"depth":261,"text":1353},{"id":1479,"depth":261,"text":1239},{"id":1580,"depth":254,"text":1581},{"id":1916,"depth":254,"text":1917},{"id":2046,"depth":254,"text":2047,"children":2400},[2401],{"id":2050,"depth":261,"text":2051},"Compose routes from middleware chains – built-ins for bearer auth, file\u002Fpage resolution, plus your own validators.","md",{},{"title":59,"description":2402},"uSn0OjqANj2NewuG2GEk7dQeIeHP2T6K1zOsMpETmb0",[2408,104],{"title":55,"path":56,"stem":57,"description":2409,"children":-1},"Get frontend URLs, breadcrumb data, and multi-language metadata for navigation and language switchers in headless frontends.",1792520764895]