[{"data":1,"prerenderedAt":981},["ShallowReactive",2],{"navigation_docs":3,"-essentials-host-owned-views":98,"-essentials-host-owned-views-surround":976},[4,26,82],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":25},"Getting Started","i-lucide-rocket","/getting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Installation","/getting-started/installation","1.getting-started/1.installation","i-lucide-download",{"title":16,"path":17,"stem":18,"icon":19},"Frontend Setup (headless)","/getting-started/frontend-setup","1.getting-started/2.frontend-setup","i-lucide-layout",{"title":21,"path":22,"stem":23,"icon":24},"Public-routes mode","/getting-started/public-routes-mode","1.getting-started/3.public-routes-mode","i-lucide-zap",false,{"title":27,"icon":28,"path":29,"stem":30,"children":31,"page":25},"Essentials","i-lucide-book-open","/essentials","2.essentials",[32,37,42,47,52,57,62,67,72,77],{"title":33,"path":34,"stem":35,"icon":36},"Blade Components","/essentials/blade-components","2.essentials/1.blade-components","i-lucide-component",{"title":38,"path":39,"stem":40,"icon":41},"Host-Owned Views","/essentials/host-owned-views","2.essentials/10.host-owned-views","i-lucide-layout-template",{"title":43,"path":44,"stem":45,"icon":46},"Filament Admin","/essentials/filament-admin","2.essentials/2.filament-admin","i-lucide-layout-dashboard",{"title":48,"path":49,"stem":50,"icon":51},"MCP Tools","/essentials/mcp-tools","2.essentials/3.mcp-tools","i-lucide-bot",{"title":53,"path":54,"stem":55,"icon":56},"Configuration","/essentials/configuration","2.essentials/4.configuration","i-lucide-settings",{"title":58,"path":59,"stem":60,"icon":61},"Tags Taxonomy","/essentials/tags","2.essentials/5.tags","i-lucide-hash",{"title":63,"path":64,"stem":65,"icon":66},"MediaLibrary Integration","/essentials/media-library","2.essentials/6.media-library","i-lucide-image",{"title":68,"path":69,"stem":70,"icon":71},"Search","/essentials/search","2.essentials/7.search","i-lucide-search",{"title":73,"path":74,"stem":75,"icon":76},"Schema","/essentials/schema","2.essentials/8.schema","i-lucide-code-2",{"title":78,"path":79,"stem":80,"icon":81},"Listing SEO","/essentials/listing-seo","2.essentials/9.listing-seo","i-lucide-list",{"title":83,"icon":84,"path":85,"stem":86,"children":87,"page":25},"Community","i-lucide-users","/community","4.community",[88,93],{"title":89,"path":90,"stem":91,"icon":92},"Contributing","/community/contributing","4.community/1.contributing","i-lucide-git-pull-request",{"title":94,"path":95,"stem":96,"icon":97},"License","/community/license","4.community/2.license","i-lucide-scale",{"id":99,"title":38,"body":100,"description":969,"extension":970,"links":971,"meta":972,"navigation":973,"path":39,"seo":974,"stem":40,"__hash__":975},"docs/2.essentials/10.host-owned-views.md",{"type":101,"value":102,"toc":961},"minimark",[103,116,125,247,260,340,353,357,488,501,544,548,553,595,612,791,806,812,816,843,846,881,885,957],[104,105,106,107,111,112,115],"p",{},"Public-routes mode ships a ",[108,109,110],"code",{},"BlogController"," with all six public actions. By default they\nrender the package's own ",[108,113,114],{},"ink::pages.*"," views. Point each action at a view your app already\nowns instead — same controller, same SEO and query behavior, your markup.",[117,118,120,121,124],"h2",{"id":119},"the-views-config-map","The ",[108,122,123],{},"views"," config map",[126,127,133],"pre",{"className":128,"code":129,"filename":130,"language":131,"meta":132,"style":132},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","'views' => [\n    'index' => null,\n    'show' => null,\n    'category' => null,\n    'tag' => null,\n    'preview' => null,\n    'feed' => null,\n],\n","config/ink.php","php","",[108,134,135,155,171,185,199,213,227,241],{"__ignoreMap":132},[136,137,140,144,147,149,152],"span",{"class":138,"line":139},"line",1,[136,141,143],{"class":142},"sMK4o","'",[136,145,123],{"class":146},"sfazB",[136,148,143],{"class":142},[136,150,151],{"class":142}," =>",[136,153,154],{"class":142}," [\n",[136,156,158,161,164,166,168],{"class":138,"line":157},2,[136,159,160],{"class":142},"    '",[136,162,163],{"class":146},"index",[136,165,143],{"class":142},[136,167,151],{"class":142},[136,169,170],{"class":142}," null,\n",[136,172,174,176,179,181,183],{"class":138,"line":173},3,[136,175,160],{"class":142},[136,177,178],{"class":146},"show",[136,180,143],{"class":142},[136,182,151],{"class":142},[136,184,170],{"class":142},[136,186,188,190,193,195,197],{"class":138,"line":187},4,[136,189,160],{"class":142},[136,191,192],{"class":146},"category",[136,194,143],{"class":142},[136,196,151],{"class":142},[136,198,170],{"class":142},[136,200,202,204,207,209,211],{"class":138,"line":201},5,[136,203,160],{"class":142},[136,205,206],{"class":146},"tag",[136,208,143],{"class":142},[136,210,151],{"class":142},[136,212,170],{"class":142},[136,214,216,218,221,223,225],{"class":138,"line":215},6,[136,217,160],{"class":142},[136,219,220],{"class":146},"preview",[136,222,143],{"class":142},[136,224,151],{"class":142},[136,226,170],{"class":142},[136,228,230,232,235,237,239],{"class":138,"line":229},7,[136,231,160],{"class":142},[136,233,234],{"class":146},"feed",[136,236,143],{"class":142},[136,238,151],{"class":142},[136,240,170],{"class":142},[136,242,244],{"class":138,"line":243},8,[136,245,246],{"class":142},"],\n",[104,248,249,250,253,254,256,257,259],{},"Every key defaults to ",[108,251,252],{},"null",". A ",[108,255,252],{}," or empty-string value falls back to the matching\n",[108,258,114],{}," view, so an existing install that never touches this key renders exactly as\nbefore. Set a key to any view name your app can resolve — a Blade view, a package view, a\nnamespaced view from another provider:",[126,261,263],{"className":128,"code":262,"filename":130,"language":131,"meta":132,"style":132},"'views' => [\n    'index' => 'blog.index',\n    'show' => 'blog.show',\n    'preview' => 'blog.preview',\n],\n",[108,264,265,277,298,317,336],{"__ignoreMap":132},[136,266,267,269,271,273,275],{"class":138,"line":139},[136,268,143],{"class":142},[136,270,123],{"class":146},[136,272,143],{"class":142},[136,274,151],{"class":142},[136,276,154],{"class":142},[136,278,279,281,283,285,287,290,293,295],{"class":138,"line":157},[136,280,160],{"class":142},[136,282,163],{"class":146},[136,284,143],{"class":142},[136,286,151],{"class":142},[136,288,289],{"class":142}," '",[136,291,292],{"class":146},"blog.index",[136,294,143],{"class":142},[136,296,297],{"class":142},",\n",[136,299,300,302,304,306,308,310,313,315],{"class":138,"line":173},[136,301,160],{"class":142},[136,303,178],{"class":146},[136,305,143],{"class":142},[136,307,151],{"class":142},[136,309,289],{"class":142},[136,311,312],{"class":146},"blog.show",[136,314,143],{"class":142},[136,316,297],{"class":142},[136,318,319,321,323,325,327,329,332,334],{"class":138,"line":187},[136,320,160],{"class":142},[136,322,220],{"class":146},[136,324,143],{"class":142},[136,326,151],{"class":142},[136,328,289],{"class":142},[136,330,331],{"class":146},"blog.preview",[136,333,143],{"class":142},[136,335,297],{"class":142},[136,337,338],{"class":138,"line":201},[136,339,246],{"class":142},[104,341,342,343,346,347,349,350,352],{},"Resolution happens once per request, through a private ",[108,344,345],{},"viewFor()"," helper on\n",[108,348,110],{}," — every action calls it instead of hardcoding ",[108,351,114],{},".",[117,354,356],{"id":355},"what-each-view-receives","What each view receives",[358,359,360,376],"table",{},[361,362,363],"thead",{},[364,365,366,370,373],"tr",{},[367,368,369],"th",{},"Action",[367,371,372],{},"View data",[367,374,375],{},"Notes",[377,378,379,394,415,429,443,476],"tbody",{},[364,380,381,386,391],{},[382,383,384],"td",{},[108,385,163],{},[382,387,388],{},[108,389,390],{},"posts",[382,392,393],{},"—",[364,395,396,400,409],{},[382,397,398],{},[108,399,178],{},[382,401,402,405,406],{},[108,403,404],{},"post",", ",[108,407,408],{},"relatedPosts",[382,410,411,414],{},[108,412,413],{},"post->tags"," is eager-loaded",[364,416,417,421,427],{},[382,418,419],{},[108,420,192],{},[382,422,423,405,425],{},[108,424,192],{},[108,426,390],{},[382,428,393],{},[364,430,431,435,441],{},[382,432,433],{},[108,434,206],{},[382,436,437,405,439],{},[108,438,206],{},[108,440,390],{},[382,442,393],{},[364,444,445,449,458],{},[382,446,447],{},[108,448,220],{},[382,450,451,405,453,405,455],{},[108,452,404],{},[108,454,408],{},[108,456,457],{},"editUrl",[382,459,460,462,463,465,466,468,469],{},[108,461,413],{}," is eager-loaded; ",[108,464,457],{}," is ",[108,467,252],{}," unless a host registers ",[470,471,473],"a",{"href":472},"#preview-edit-link",[108,474,475],{},"Ink::resolvePreviewEditUrlUsing()",[364,477,478,482,486],{},[382,479,480],{},[108,481,234],{},[382,483,484],{},[108,485,390],{},[382,487,393],{},[104,489,490,492,493,495,496,498,499,352],{},[108,491,408],{}," and ",[108,494,457],{}," on ",[108,497,220],{}," are new — earlier versions passed only ",[108,500,404],{},[502,503,504,527],"caution",{},[104,505,506,507,510,511,514,515,518,519,523,524,526],{},"Publishing views (",[108,508,509],{},"php artisan vendor:publish --tag=ink-views",") is not the recommended way\nto customize the six page views above. Laravel resolves ",[108,512,513],{},"resources/views/vendor/ink/**","\nahead of ",[108,516,517],{},"ink::**"," automatically, so publishing ",[520,521,522],"em",{},"works"," — but the file it creates is a\nfrozen copy of package markup from the day you published it. It will not receive upstream\nfixes, and nothing will tell you when it's drifted. Pointing ",[108,525,123],{}," at your own view avoids\nboth problems: you own the markup from the start, and ink's own pages keep improving\nunderneath you without needing a merge.",[104,528,529,530,533,534,405,537,540,541,543],{},"Publishing is still how you customize the ",[470,531,532],{"href":34},"Blade components","\n(",[108,535,536],{},"post-card",[108,538,539],{},"post-header",", …) — those aren't covered by the ",[108,542,123],{}," map.",[117,545,547],{"id":546},"preview-edit-link","Preview edit link",[104,549,550,552],{},[108,551,475],{}," registers how to build the \"edit this post\" link shown\non the preview page:",[126,554,556],{"className":128,"code":555,"language":131,"meta":132,"style":132},"public static function resolvePreviewEditUrlUsing(?Closure $callback): void\n",[108,557,558],{"__ignoreMap":132},[136,559,560,564,567,570,574,577,581,584,588,591],{"class":138,"line":139},[136,561,563],{"class":562},"spNyl","public",[136,565,566],{"class":562}," static",[136,568,569],{"class":562}," function",[136,571,573],{"class":572},"s2Zo4"," resolvePreviewEditUrlUsing",[136,575,576],{"class":142},"(?",[136,578,580],{"class":579},"sBMFI","Closure",[136,582,583],{"class":142}," $",[136,585,587],{"class":586},"sTEyZ","callback",[136,589,590],{"class":142},"):",[136,592,594],{"class":593},"sbssI"," void\n",[104,596,597,598,600,601,603,604,607,608,611],{},"With nothing registered, ",[108,599,457],{}," is always ",[108,602,252],{}," and no edit link renders. Register a\ncallback in a service provider's ",[108,605,606],{},"boot()"," — never in config, since a closure in a config\nfile breaks ",[108,609,610],{},"config:cache",":",[126,613,615],{"className":128,"code":614,"language":131,"meta":132,"style":132},"use Relaticle\\Ink\\Ink;\nuse Relaticle\\Ink\\Models\\Post;\n\nInk::resolvePreviewEditUrlUsing(fn (Post $post): ?string =>\n    auth('sysadmin')->check()\n        ? PostResource::getUrl('edit', ['record' => $post], panel: 'sysadmin')\n        : null);\n",[108,616,617,638,660,666,702,725,783],{"__ignoreMap":132},[136,618,619,622,625,628,631,633,635],{"class":138,"line":139},[136,620,621],{"class":593},"use",[136,623,624],{"class":586}," Relaticle",[136,626,627],{"class":142},"\\",[136,629,630],{"class":586},"Ink",[136,632,627],{"class":142},[136,634,630],{"class":586},[136,636,637],{"class":142},";\n",[136,639,640,642,644,646,648,650,653,655,658],{"class":138,"line":157},[136,641,621],{"class":593},[136,643,624],{"class":586},[136,645,627],{"class":142},[136,647,630],{"class":586},[136,649,627],{"class":142},[136,651,652],{"class":586},"Models",[136,654,627],{"class":142},[136,656,657],{"class":586},"Post",[136,659,637],{"class":142},[136,661,662],{"class":138,"line":173},[136,663,665],{"emptyLinePlaceholder":664},true,"\n",[136,667,668,670,673,676,679,682,685,687,689,691,693,696,699],{"class":138,"line":187},[136,669,630],{"class":579},[136,671,672],{"class":142},"::",[136,674,675],{"class":572},"resolvePreviewEditUrlUsing",[136,677,678],{"class":142},"(",[136,680,681],{"class":562},"fn",[136,683,684],{"class":142}," (",[136,686,657],{"class":579},[136,688,583],{"class":142},[136,690,404],{"class":586},[136,692,590],{"class":142},[136,694,695],{"class":142}," ?",[136,697,698],{"class":593},"string",[136,700,701],{"class":142}," =>\n",[136,703,704,707,709,711,714,716,719,722],{"class":138,"line":201},[136,705,706],{"class":572},"    auth",[136,708,678],{"class":142},[136,710,143],{"class":142},[136,712,713],{"class":146},"sysadmin",[136,715,143],{"class":142},[136,717,718],{"class":142},")->",[136,720,721],{"class":572},"check",[136,723,724],{"class":142},"()\n",[136,726,727,730,733,735,738,740,742,745,747,750,753,755,758,760,762,764,766,769,772,774,776,778,780],{"class":138,"line":215},[136,728,729],{"class":142},"        ?",[136,731,732],{"class":579}," PostResource",[136,734,672],{"class":142},[136,736,737],{"class":572},"getUrl",[136,739,678],{"class":142},[136,741,143],{"class":142},[136,743,744],{"class":146},"edit",[136,746,143],{"class":142},[136,748,749],{"class":142},",",[136,751,752],{"class":142}," [",[136,754,143],{"class":142},[136,756,757],{"class":146},"record",[136,759,143],{"class":142},[136,761,151],{"class":142},[136,763,583],{"class":142},[136,765,404],{"class":586},[136,767,768],{"class":142},"],",[136,770,771],{"class":579}," panel",[136,773,611],{"class":142},[136,775,289],{"class":142},[136,777,713],{"class":146},[136,779,143],{"class":142},[136,781,782],{"class":142},")\n",[136,784,785,788],{"class":138,"line":229},[136,786,787],{"class":142},"        :",[136,789,790],{"class":142}," null);\n",[104,792,793,794,796,797,253,799,801,802,805],{},"The callback receives the ",[108,795,657],{}," and must return a string or ",[108,798,252],{},[108,800,252],{},", or any\nnon-string return, is treated as \"no link\" — a misconfigured ",[520,803,804],{},"return value"," never throws.\nIf your callback itself throws, that exception is not caught and will surface as a 500 on\nthe preview page; ink only guards the return value, not the callback's own execution.\nWhich panel and which guard own the blog admin is a host decision; ink does not guess at\nit.",[104,807,808,811],{},[108,809,810],{},"\u003Cx-ink::preview-banner :post=\"$post\" :editUrl=\"$editUrl\" />"," is the shipped component that\nrenders this link.",[117,813,815],{"id":814},"route-middleware","Route middleware",[126,817,819],{"className":128,"code":818,"filename":130,"language":131,"meta":132,"style":132},"'middleware' => ['web'],\n",[108,820,821],{"__ignoreMap":132},[136,822,823,825,828,830,832,834,836,839,841],{"class":138,"line":139},[136,824,143],{"class":142},[136,826,827],{"class":146},"middleware",[136,829,143],{"class":142},[136,831,151],{"class":142},[136,833,752],{"class":142},[136,835,143],{"class":142},[136,837,838],{"class":146},"web",[136,840,143],{"class":142},[136,842,246],{"class":142},[104,844,845],{},"Applied to the entire blog route group. Add your own alongside it — for example a host that\nserves markdown to AI crawlers:",[126,847,849],{"className":128,"code":848,"filename":130,"language":131,"meta":132,"style":132},"'middleware' => ['web', ProvideMarkdownResponse::class],\n",[108,850,851],{"__ignoreMap":132},[136,852,853,855,857,859,861,863,865,867,869,871,874,876,879],{"class":138,"line":139},[136,854,143],{"class":142},[136,856,827],{"class":146},[136,858,143],{"class":142},[136,860,151],{"class":142},[136,862,752],{"class":142},[136,864,143],{"class":142},[136,866,838],{"class":146},[136,868,143],{"class":142},[136,870,749],{"class":142},[136,872,873],{"class":579}," ProvideMarkdownResponse",[136,875,672],{"class":142},[136,877,878],{"class":593},"class",[136,880,246],{"class":142},[117,882,884],{"id":883},"the-shallow-config-merge-trap","The shallow config-merge trap",[502,886,887,914,943],{},[104,888,889,890,893,894,897,898,900,901,905,906,909,910,913],{},"If your app has already run ",[108,891,892],{},"php artisan vendor:publish --tag=ink-config",", be aware that\nLaravel's ",[108,895,896],{},"mergeConfigFrom"," — which is how the package's config defaults reach your\n",[108,899,130],{}," — is a ",[902,903,904],"strong",{},"shallow"," merge. It's ",[108,907,908],{},"array_merge($packageDefaults, $yourConfig)",":\nfor any top-level key present in both arrays, your value wins ",[902,911,912],{},"wholesale",", array or not.",[104,915,916,917,492,919,921,922,925,926,929,930,932,933,936,937,939,940,942],{},"New top-level keys like ",[108,918,123],{},[108,920,827],{}," merge in fine — your published file simply\ndoesn't have them, so the package default fills the gap. But a key added ",[520,923,924],{},"inside"," an\nexisting array, such as a new flag under ",[108,927,928],{},"features",", will not reach you: your published\n",[108,931,928],{}," array replaces the package's entirely, new subkey and all. This isn't\nhypothetical — it already bit a host of this package: ",[108,934,935],{},"ink.features.mcp"," silently resolved\nto ",[108,938,252],{}," after they'd published ",[108,941,130],{}," before that flag existed.",[104,944,945,946,948,949,956],{},"After upgrading, diff your published ",[108,947,130],{}," against the package's\n",[470,950,954],{"href":951,"rel":952},"https://github.com/relaticle/ink/blob/main/config/ink.php",[953],"nofollow",[108,955,130],{}," and add any\nnew subkeys by hand.",[958,959,960],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":132,"searchDepth":157,"depth":157,"links":962},[963,965,966,967,968],{"id":119,"depth":157,"text":964},"The views config map",{"id":355,"depth":157,"text":356},{"id":546,"depth":157,"text":547},{"id":814,"depth":157,"text":815},{"id":883,"depth":157,"text":884},"Render ink's controllers through views your app already owns, and control the preview edit link.","md",null,{},{"icon":41},{"title":38,"description":969},"jorCxu_Bd_9zkB75tujQ4EPfE7Fsu72bQ7zvFuYVkmk",[977,979],{"title":33,"path":34,"stem":35,"description":978,"icon":36,"children":-1},"All available Blade components for building your blog frontend.",{"title":43,"path":44,"stem":45,"description":980,"icon":46,"children":-1},"Managing blog posts, categories, and tags in the Filament admin panel.",1786967163821]