Please, post some Router.js code examples that works!

Hi to all,
it’s been weeks I trying to get router.js works.

I read and read and read all Wix Api references and trying a lot of alternatives,
perhaps I’m not so smart, it’s possible, but if Wix was thought for Dummies, so, it’s failing its goal.

Or, at opposite, router.js doesn’t work as It should do.

Please, programmers of the platform Wix, could I have an answer ?

Up

Hi! Sorry for the delay, i can help you from now)

Please, what is the problems which you met?
Actually, currently when you create custom router, you have an example which works. It’s only difference is that fact that it takes “items” from const array, but in real situation you probably will take data from collection with wixData module

Thanks Michail !
I have in my mind two scenarios
1st. when a user click a static link of a page of mysito, based on some conditions I would to decide where to redirect user, on another static or dynamic page of mysito.
2nd. when a user want to access to a forbidden page, I would redirect on another page I decided.

But I didn’t get how I can get router works.
Please could you lay down for me some sample examples please ?
Thanks in advance
Mauro

Actually, there are some examples (simple enough) on this link -

This one for example:


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");
  }
  else {
    // Return 404
    return notFound();
  }
}

Router is some tool which controls redirection for ANY requests, which starts with some specific (whch you choose when creating custom router) site url + prefix. In this case, this function is executed EACH time when you try to open any page like
https://user.wixsite.com/mysite/myRouter/
So in this specific case, if you try to open https://user.wixsite.com/mysite/myRouter/good, you will go to if condition and router will redirect you to myRouter-page with HTTP status 200 (all is ok). For any other request with this preix, it will show you standard 404 page.

I can’t paste you exact code for your site, you should develop it by yourself. But i can answer any specific questions about functions or smth else
So ask)

Hi Mikhail thanks so much,

unfortunaly I tried this example you posted in order to train myself on code router, but it doesn’t work.
Did you speak on your personal experience, did you try this code ?
Let me know please.

Up

Yes for sure. It works

But it’s not only this function which is needed, you also need sitemap function and custom router page.
THis is a screenshot of working site with custom router:

https://www.screencast.com/t/Zepb8sLf

You can check site itself here:
https://mikhails8.wixsite.com/mysite-408/myrouter/good
this url shows that specific page. Any other url like
https://mikhails8.wixsite.com/mysite-408/myrouter/good111
will show 404.

Ah, ooK, so it’s important also the Sitemap function !! But this also for after_ and before_ router ?
So definitively I didn’t get Sitemap function reading the Wix API Sitemap function.
Could you explain me better, please ?
Thanks so much in advance
Mauro

after_ and before_ router - these are hooks, which can be used to execute smth befaore or after router. You don’t need to use them in general.

Sitemap function is something which generates LIST of possible site pages. This list is used everywhere on the site in links dialogs (and, it’s used to create pages for seo bots from google).
It actually contains all possible pages which can be created with custom router.
In my case i just created 1 page with name good, but i believe i can also skip this part, it will work without it

As dynpages feature in general is just limited custom router, this sitemap generating process is accomplished automatically - it just takes all possible item for dyn page and generate this list
For custom router you need to controll this process manually

So, if I would want to control a user that’s a signed site member but that doesn’t still confirmed himself by clicking a triggered email I sent him, could I use wixUsers or wixData API in backend to realize control on him ?

eg. IF in the collection of Members the members.field of user that’s logged IS TRUE because he clicked confirmation email, THEN GO somewhere, ELSE goto PAGE "we sent to you an email, please confirm "

OR simpler, If I browse to:
https://costieraslow.wixsite.com/ilmiosito04/Members/3403a11e-b831-4494-80b0-350424a09a5c
but I’m not logged , in which way I could redirect myself on a page like PLEASE LOG YOU, in place of to get the 403 forbidden page ?

You can do this without router.

https://www.wix.com/code/reference/wix-users.html#onLogin
Create this event on site level (to cover any page on site)
Check this field in database with wixdata, if it’s false,
with this function

redirect user to some hidden specific page without menu, saying “please confirm your registration”

Perhaps something miss !

User in order to confirm have to receive via triggered email an unique custom link, is the path of the user dynamic page (with its userID):
https://costieraslow.wixsite.com/ilmiosito04/Members/3403a11e-b831-4494-80b0-350424a09a5c
here user will find the page where he could confirm.
BUT when user receives the email with the custom link and he’s not logged on the site, when he clicks on the link, he will receive an 403 forbidden page !
HERE I need a hooks router that could manage this situation.
HOW can I do ? I would to use the redirect() function, but I have to believe that probably that in this moment hooks router doesn’t work, or nobody is able to let me use it.

«…Use this hook to change the router’s response based on the data that was retrieved…Typically, the response is created using one of the ok() , forbidden() , notFound() , redirect() , or sendStatus() functions…»

// In routers.js
import {ok, forbidden} from 'wix-router'; 
export function myRouter_afterRouter(request, response) {
if (some_condition) return ok("different-page", response.data, response.head);
else if (other_condition) return response; 
else return forbidden(); }

I have made an example app to show how to create confirmation email handler with router.

  1. You need to disable login from social and community in page settings
    http://joxi.net/bmoqgpdFMRGWRA.png
    http://dl4.joxi.net/drive/2018/05/31/0030/3214/1997966/66/7d67d24365.png.
  2. Create triggered email that will receive url for registration as variable.
    http://dl4.joxi.net/drive/2018/05/31/0030/3214/1997966/66/2c657e7387.png
  3. Add following code
//home page frontend
 
import wixUsers from 'wix-users';
import wixLocation from 'wix-location';
import wixData from 'wix-data';

$w.onReady(function () {
    $w('#signUp').onClick( async event=>{
 try{
 //register user and get his id,email
 const user = await wixUsers.promptLogin('signup');
 const email = await user.getEmail();
 try{
 //insert user into users db(hook will set additional fields)
 const insertedUser = await wixData.insert('users',{title:email,user_id:user.id});
 //send confirm email with confirmation code to user
                wixUsers.emailUser("QtcMmwf", insertedUser.user_id, {
                    variables: {
                        url: `${wixLocation.baseUrl}/r/${insertedUser.confirmation_code}`
                    }
                });
                $w('#success').show();
            }catch(e){
                console.log(e);
                $w('#error').show();
            }
        }catch(e){
            console.log(e);
            $w('#error').show();
        }
    });
    $w('#logout').onClick(event=>{
        wixUsers.logout();
    });
});


 //data.js (for hooks) backend

export function users_beforeInsert(item, context) {
 //set additional fields before insert
    item.confirmation_code = generateCode(item.user_id);  
    item.confirmed = false;
 return item;
}

//generate hash for email confirmation. You write your code generator here 
function generateCode(id){
       //your  unique code  or hash generating function
}
//routers.js backend
import {ok, notFound } from "wix-router"; 
import wixData from 'wix-data';

export async function r_Router(request) {
 const url = request.url.split('/');
 const confirmation_code = url[url.length-1]; //get confirmation code from url
 let response;
 try{
 const query =  await wixData.query('users').eq('confirmation_code',confirmation_code).eq('confirmed',false).find(); //try to find not confirmed user with this code
 const user = query.items[0];
 if(user){
 //confirm user and save him in db if n
            user.confirmed = true;
 try{
 const updatedUser = await wixData.update('users',user,{"suppressAuth":true,"suppressHooks": false});
                response = {message:'Email confirmed!'};
            }catch(e){
                response = {error:e};
            }
        }else {
 //response = {error:'no users found'}; for debug
         return notFound();
        }
    } catch(e){
 //response = {eror:e}; for debug
 return notFound();
    }
 return ok('r-page',response);//404 or different code if error;
}

//r-page (router page)
import wixWindow from 'wix-window';

$w.onReady(function () {
 const routerData = wixWindow.getRouterData(); //{error:'text} or {message:'text'};
 if (routerData.error){
        $w('#message').text = routerData.error; 
    }else {
        $w('#message').text = routerData.message;
    }
});

Ooooh I just read the post, I have not try yet neither studied it, but BIIIIG ANDRII !!

Hi Andrii,
could you explain better in pseudocode your router.js routine, please ?

Furthermore I would like to ask for clarification if possible. In the home page you refer to a ‘r’ page:

url: `${wixLocation.baseUrl}/r/${insertedUser.confirmation_code}`  

but in router.js I see a return to the ‘r-page’ page:

return ok('r-page',response);//404 or different code if error;

Is It a misprint or I have to study deeper ?

thanks in advance
Mauro

Andrii

it’s works at half.
It was able to set as true the field in collection ‘users’, but router.js isn’t able to forward to the final r-page.

Could you control my work, please ? That’s the link:
https://costieraslow.wixsite.com/test

thank in advance
Mauro

Hello Mauro Vento Avyno .

Looks like we found a bug. Somehow both if and else are evaluated is this code

const query =  await wixData.query('users').eq('confirmation_code',confirmation_code).eq('confirmed',false).find(); //try to find not confirmed user with this code
 const user = query.items[0];
 if(user){ //here user is updated successfully,but else also evaluates;
 //confirm user and save him in db if n
            user.confirmed = true;
 try{
 const updatedUser = await wixData.update('users',user,{"suppressAuth":true,"suppressHooks": false});
                response = {message:'Email confirmed!'};
            }catch(e){
                response = {error:e};
            }
        }else {
 //response = {error:'no users found'}; for debug
 return notFound();
        }
    } catch(e){
 //response = {eror:e}; for debug
 return notFound();
    }

I created a bug report for this issue. For now, please try this code instead.
TL;DR.
changed if (query.items.length) to if (!query.items.length), to put user not found code in the top.

//routers.js
import {
    ok,
    notFound
} from "wix-router";
import wixData from 'wix-data';

export async function r_Router(request) {
 const url = request.url.split('/');
 const confirmation_code = url[url.length - 1]; //get confirmation code from url
 let response;
 try {
 const query = await wixData.query('users').eq('confirmation_code', confirmation_code).eq('confirmed', false).find(); //try to find not confirmed user with this code
 const user = query.items[0];
 if (!query.items.length) { 

            response = {
                error: 'no users found',
                items: query.items
            };
 return ok('r-page', response);
        } else {
 //confirm user and save him in db if n
            user.confirmed = true;
 try {
 const updatedUser = await wixData.update('users', user, {
 "suppressAuth": true,
 "suppressHooks": false
                });
                response = {
                    message: 'Email confirmed!'
                };
 return ok('r-page', response);
            } catch (e) {
                response = {
                    eror: e
                };
 return ok('r-page', response);
            }
        }
    } catch (e) {
        response = {
            eror: e
        };
 return ok('r-page', response);
    }
}

About this code -yes /r/ is routers name. Also i use wixLocation.baseUrl, so it will work both on free and premium sites

 url: `${wixLocation.baseUrl}/r/${insertedUser.confirmation_code}`  

Hi Andrii, it works ! I’m touched :°°°
Now I’m going to debug and study your code in order to understand it and try to manage.

Andrii, please, what does mean " if (query.items.length) to if (!query.items.length) " ?
I didn’t found anything in the net about the exclamation mark before query :open_mouth: