Best Practice for Routing

What I’m trying to do:
I’m transitioning to using the new routing library to add more features and support better SEO. I’d like to know what are some best practices to avoid having server failures when your pages import anvil.js or any other anvil component?

What I’ve tried and what’s not working:
I have a page that imports a library with the following imports:

from anvil import Notification, TextBox, alert
from anvil_extras.messaging import Publisher
from firebase.firebase_client import authentication, firestore, initialize_app

import anvil.js

This fails with the first line since these libaries dont exist on the server side. I could import them in the methods they’re used in, but that seems messy.

Am I overlooking something?

Thanks community!

Update 1:

Clone to replicate the issue: Anvil | Login

if you route directly to the url /about page (has to be published), the error will occur. Here is a link

How are you importing the form on the server side? You shouldn’t have to import your forms at all, but on the server the Router class should be strings of the form names:

from routing.router import Route

IndexRoute = Route.create(path="/", form="Pages.Index")
AboutRoute = Route.create(path="/about", form="Pages.About")
ContactRoute = Route.create(path="/contact", form="Pages.Contact")
1 Like

I actually didnt have the server activated in this project.

After activation, I added a server module labeled ServerRoutes.py, per the documentation. and added the following line:

import anvil.server
from . import routes

However, the same error occurs.

Here is a very simple clone to replicate the issue:

Let me start with, I still would appreciate some insight from those with more history & experience with this issue.

I was able to mitigate my issues with the following tactics:

  1. lazy importing to prevent the server from importing client libraries
  2. converting class attributes to properties
    • This was necessary for class instantiated that had attributes that were classes whom called client only methods.

I don’t like how specific these changes have to be, but maybe this is the way. -Mandalorins–

The minimal example doesn’t seem to replicate the issue.

So long as your routes module doesn’t import client specific stuff you should be ok
if you are importing client only modules in your routes module, then things won’t work, because ultimately that will end up being imported on the server.


Side note:
I’ve updated the docs to emphasise that you don’t need to import the routes module on the server (or the client).
The routing dependency will do this for you.

2 Likes

The client specific items were being imported in the routes library. Those were the lazy imports I had to implement. After I moved those there was still one unresolved issue.

There was a call to a firebase database in the form init function of the form being created by the route. This database had to be initiated on the client side. I moved that logic to the “show” event handler and that resolved the last bit.

After your explanation and call out. It was the fact I was importing Notification in the routes module. I updated the example, but its exactly what you stated.

Thanks @stucork and @duncan_richards12 !

1 Like

re the clone app, i suspect you’re working on a branch, clones only clone master.

Here is a gif: Its as you said:

route_issue

1 Like