What is a router?
When the user enters the URL in the browser, the browser forwards the URL data to the server(router) based on the URL the server sends the data back to the browser. In the case of Wix, we can create a router page with dragging and dropping elements and connect the element data based on the router data or we can redirect the User to 403 Page (Unauthorised) or 404 Page(Where there is no data found for that Url).
When you should use a router page?
Here are some cases when you need to use wix-router
Having a custom membership built with stripe and check the user is a premium member before redirecting to a premium page
Allow specific content to view in the database
e.g: Let say we have a list of article and if one of the articles is set to public (it should be view by all user). In this case, you will need to use a router to check if the article is public and based on that we can view the article or if it's not a public article, we can show a 403 Unauthorised page
Let's get started
In this tutorial, we are building an article page that can be view to the public only (if the article author is set to public).
There will be an Article database with a list of article titles, images, and a public column to store if the article can be view by the public or not. Instead of using a dynamic page. We are going to use a router page. So, we can override the permission, if the article is set to public and this is the safest way, as the article owner can only create, read, update, delete the article and we can also override the data only if the article data is set to public. Let's create a new blank site, and turn on the dev mode.
Create a new router page
Router Page is similar to dynamic page. you will design the page usually and add the element and connect the element via code. the data for that page will be passed from the router.
A popup will show as below, enter the router name and click on the "Add & Edit Code"
This will create a routers.js in the backend file
With 2 function
article_Router - So whenever someone goto Url "/article-page", this function will be trigger with the user detail and URL details and it should return either ok(), error page like notFound() or forbidden()
article_SiteMap - This function return an array of available pages to create a sitemap for SEO bot.
Before writing code in the routers.js, let's create a database(Collection).
Create a database
Let's create a new collection
Database name and permission
Set it can only view by article owner
Let's create a three column for simplicity
Sync the data to live database
Edit router.js code
URL : https://salman2301.wixsite.com/wix-router/{router page name}/{article title} E.g: https://salman2301.wixsite.com/wix-router/article/Do-more-in-less-time Do-more-in-less-time is the title of the article title, which we can get from the code and filter the database and view the page Every time if someone lands on the "/article" router will run the below logic
Let's breakdown the logic
Get the path name from the request URL
If the article name matches with the database name, return ok( )
Else return notFound( )
If the article is public
Show the page and handle SEO ( return ok( ) )
also add sitemap entry, for SEO bots to index the pages
If the article is not public
Check if the user who requested is the owner of the article, if it's true
Show the article ( return ok( ) )
Return forbidden( ); this will show the 403 Unauthorise page
Commented code
Check the comment explaining the code each line.
// import ok, notFound, forbidden page
// import WixRouterSitemapEntry allow use to create a sitemap
import {ok, notFound, forbidden, WixRouterSitemapEntry } from "wix-router";
// import wixData to query the Article database
import wixData from "wix-data";
// This function will trigger, every time someone requested
// "/article" page
export async function article_Router(request) {
// Get the path name /article/{path}
const path = request.path[0];
// If there is no path return 404 error page
if(!path) return notFound();
// replace the dash "-" with space " "
const title = path.replace(/\-/g, " ");
// Search for the title name on the Article Database
// Set the Options to suppressAuth true
// So, we can override the permission and view the article
const data = await wixData.query("Article").eq("title" , title).limit(1).find({suppressAuth: true});
if (data.length > 0) {
// store the article data
const article = data.items[0];
if(article.public) {
// create the SEO based on the article
const seoData = {
title: article.title,
description: "This is a description of " + article.title + " page",
noIndex: false,
metaTags: {
"og:title": article.title,
"og:image": article.image
}
};
// Show the item page and pass the data to frontend
return ok("article-page", article, seoData);
} else {
// if the article is not public
// check if the requested user id match with the article owner
// if it match show the page
if(request.user.id === article._owner) {
// show the article
// do not handle SEO
return ok("article-page", article);
} else {
// since the article is not public
// and requested user is not the owner of the article
// return 403 page
return forbidden();
}
}
}
// Return 404 if there is not article found for the title name
return notFound();
}
// return array of sitemaps
// each sitemap contains title, url, pageName
export async function article_SiteMap(sitemapRequest) {
// get the list of article which is set to public
const articleData = await wixData.query("Article").eq("public", true).limit(999).find({suppressAuth: true});
// loop through each article
// generate array of site map
const siteMapEntries = articleData.items.map(el =>{
// get the article title and replace the space " " with dash "-"
let { title } = el;
title = title.replace(/\s/g , "-")
// get the entry from WixRouterSitemapEntry and update the fields
const entry = new WixRouterSitemapEntry(title);
entry.pageName = title; // The name of the page in the Wix editor to render
entry.url = "/article/" + title ; // Relative URL of the page
entry.title = title; // For better SEO - Help Google
return entry;
});
return siteMapEntries;
}
Same code but less commented code
import {ok, notFound,forbidden, WixRouterSitemapEntry } from "wix-router";
import wixData from "wix-data";
export async function article_Router(request) {
// Get item name from URL request
const path = request.path[0];
if(!path) return notFound();
const title = path.replace(/\-/g, " ");
// Get the item data by name
const data = await wixData.query("Article").eq("title" , title).limit(1).find({suppressAuth: true});
console.log({data, title});
if (data.length > 0) {
const article = data.items[0];
if(article.public) {
// Define SEO tags
const seoData = {
title: article.title,
description: "This is a description of " + article.title + " page",
noIndex: false,
metaTags: {
"og:title": article.title,
"og:image": article.image
}
};
console.log("returning ok : " , article);
// Render item page
return ok("article-page", article, seoData);
} else {
if(request.user.id === article._owner) {
return ok("article-page", article);
} else {
return forbidden();
}
}
}
// Return 404 if item is not found
return notFound();
}
export async function article_SiteMap(sitemapRequest) {
const articleData = await wixData.query("Article").eq("public", true).limit(999).find({suppressAuth: true});
const siteMapEntries = articleData.items.map(el =>{
let { title } = el;
title = title.replace(/\s/g , "-")
const entry = new WixRouterSitemapEntry(title);
entry.pageName = title; // The name of the page in the Wix editor to render
entry.url = "/article/" + title ; // Relative URL of the page
entry.title = title; // For better SEO - Help Google
return entry;
});
return siteMapEntries;
}
Edit the router page
Drag and drop the element in our case, we will drag the text element and the image element and let's write the page code to connect the element from the router data.
// page code
import wixWindow from 'wix-window';
$w.onReady(function () {
// get the router data ok("page-name", routerData, seoData);
let data = wixWindow.getRouterData();
// map the data to the element
$w('#textTitle').text = data.title;
$w('#imageMain').src = data.image;
$w("#imageMain").alt = data.title;
});
Site Monitoring
The router page runs only on the server. so the browser can't catch the logs. but there is a better way to check the logs, you can use site monitoring which is tool built by Wix to show all the realtime logs. The logs can be caught once you keep the site monitoring page open
and then navigate to one of the article pages to trigger the logs.
The logs will be log out and you can click on to view more.
to goto site monitoring.
site dashboard > setting > Site Monitoring > View Site events (open) Click here to read more: https://support.wix.com/en/corvid-by-wix/site-monitoring
Conclusion and Testing
Hope you enjoy the article, click on the following link to test the URL Article page set to public https://salman2301.wixsite.com/wix-router/article/Do-more-in-less-time https://salman2301.wixsite.com/wix-router/article/Top-3-place-to-travel https://salman2301.wixsite.com/wix-router/article/Easy-way-to-reduce-weight https://salman2301.wixsite.com/wix-router/article/How-to-make-Pancake
403 Article page
404 Article page
Reference Links
1. https://www.wix.com/corvid/reference/wix-router.html 2. https://www.wix.com/corvid/reference/wix-window.html#getRouterData 3. https://support.wix.com/en/corvid-by-wix/site-monitoring 4. https://support.wix.com/en/article/corvid-creating-a-router
Author
by Salman
Stuck on a project? Hire Salman!
Email: admin@salman2301.com
Hello Marisa,
Make sure that you are typing it in correctly. Sometimes extra spaces get added by accident, causing an error in the code.
Try deleting and adding it again.
You can also try copying it exactly as it is written from the Velo documentation that Wix provides:
https://www.wix.com/velo/reference/wix-router/router
Hi! I am trying to use this code but when I type the line import {ok, notFound} from 'wix-router'; I keep getting the error that the module wix-router is not found. I am wondering if you might have any solutions for this problem? I tried contacting wix customer service and was just told there was nothing they could do and then was hung up on :(