> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt # Method name: ok(Page: any, routerReturnedData: object, head: HeadOptions, options: Options) # Method package: wixRouter # Method menu location: wixRouter --> ok # Method Link: https://dev.wix.com/docs/velo/events-service-plugins/routers/service-plugins/wix-router/ok.md # Method Description: Returns the `WixRouterResponse` object with a status code 200 (OK) and instructs the router to show the selected page. The `ok()` function is used in the [`router()`](#router) and [`afterRouter()`](#afterRouter) hooks to continue the routing process to the specified page with a successful HTTP response code. The specified page must be a page found under the given router in the Page Code section of the [Code sidebar](https://dev.wix.com/docs/develop-websites/articles/workspace-tools/velo-workspace/workspaces/wix-studio-working-with-the-code-panel.md#page-code). For example, if you want to route to **myRouter-page** from the `myRouter_Router()` function, **myRouter-page** must be in the **MyRouter Pages (Router)** section of your site's Code sidebar. Optionally, you can pass the `routerReturnedData` object to be used by the page routed to and the `head` options object for the page. The page routed to accesses the data passed to it using the [`getRouterData()`](https://dev.wix.com/docs/velo/api-reference/wix-window-frontend/get-router-data.md) function of [`wix-window-frontend`](wix-window-frontend.html) with optional data and HTML header. For enhanced performance, you can also pass a `cache` object in the `options` parameter to temporarily store the return value of the `ok()` function for a specified duration. This reduces response times and eliminates the need to repeatedly fetch router data. You can set the duration, in seconds, for which you want the return value to be cached. The default is approximately 1 week. Assign identifiers to caches using the `tags` property of the `cache` object. Tags allow you to specify cached return values that may later require invalidation due to a significant change in your data. To invalidate router caches, use the [`invalidateCache()`](https://dev.wix.com/docs/velo/api-reference/wix-cache-backend/cache/invalidate-cache.md) function from the `wix-cache-backend` module. Once invalidated, the return value is re-cached upon the subsequent router page request. Learn more about [router caching](https://dev.wix.com/docs/develop-websites/articles/best-practices/caching/about-router-caching.md). >__Important:__ > - The `tags` property is required for caching. Without tags, nothing is cached. > - The `invalidateCache()` method from [wix-cache-backend](https://dev.wix.com/docs/velo/api-reference/wix-cache-backend/cache/invalidate-cache.md) is currently in developer preview. # Method Code Examples: *** Note: do not assume any prop names or enum values other than the ones in the example. ## Create an okay response ```javascript import {ok} from 'wix-router'; export function myRouter_Router(request) { return ok("router-page"); } ``` ## Create an okay response with data and head options ```javascript import {ok} from 'wix-router'; export function myRouter_Router(request) { return ok("router-page", dataObj, headOpts); } ``` ## Create an okay response with data, head, and caching options ```javascript import { ok } from 'wix-router'; export function myRouter_Router(request) { let dataObj = { "field1": "value1", "field2": "value2" }; let headOptions = { "title": "A page title", "metaTags": [ { "name": "description", "content": "A page description" }, { "name": "keywords", "content": "Velo Example" }, { "name": "robots", "content": "noindex" }, { "name": "og:title", "content": "The Title" }, { "property": "og:image", "content": "wix:image://v1/6...2.jpg/a.jpg#originWidth=970&originHeight=120" } ], "links": [ { "rel": "canonical", "href": "http://mysite.com/somePage.html" } ], "structuredData": [ { "@context": "http://schema.org", "@type": "Organization", "name": "My Organization Name", "url": "https://www.myorgdomain.com" }, { "@context": "http://schema.org", "@type": "Person", "email": "mailto:john.doe@somedomain.com", "jobTitle": "Professor", "name": "John Doe", "telephone": "(555) 555-555" } ] }; let cacheOptions = { cache: { tags: [ "myTagForCachedRouter", "routerPage" ] }, } return ok("router-page", dataObj, headOptions, cacheOptions); } ``` ## Create an okay response and cache the return value ```javascript import { ok } from "wix-router"; export function myRouter_Router(request) { return ok("router-page", {}, {}, { cache: { tags: ["myTagForCachedRouter"], ttl: 302400 } } ); } ``` ## Cache the return value of `ok()` if the router path begins with the word "good" ```javascript import { ok, notFound } from "wix-router"; export function myRouter_Router(request) { // URL looks like: // https://mysite.com/myRouter/good // or: // https://user.wixsite.com/mysite/myRouter/good const status = request.path[0]; if (status === "good") { // Show a page return ok("myRouter-page", {}, {}, { cache: { tags: ["goodPage"], ttl: 864000 } }); } else { // Return 404 return notFound(); } } ``` ---