Serving your app’s user interface from HTTP routes

Anvil lets you serve your app’s user interface directly from HTTP endpoints using AppResponder. This is useful when you want a URL to load a specific Form.

AppResponder lets you do things that a plain HTTP response can’t, like setting the page title and metadata for a specific route, and pre-loading data into your Form before it initialises.

If you just want URL-based navigation within your app, the Routing module is a better fit. This guide is for cases where you need direct control over what gets served from a route and how.

Setting the page title and description

By default, every page in your Anvil app shares the same title. For example, if a user shares a link to /directory, the preview will show your app’s default title rather than anything meaningful about that page. You can use AppResponder to set the title and description of a specific page.

@anvil.server.route("/directory")
def serve_directory(**p):
    responder = anvil.server.AppResponder(
        meta={
            "title": "All Employees",
            "description": "Meet the Team",
        }
    )
    return responder.load_form("DirectoryForm")

Using theme assets in meta tags

If you want an image to appear in social sharing previews, you can reference an image from your app’s assets by prefixing the value with "asset:". Anvil resolves the asset path to the correct URL automatically.

responder = anvil.server.AppResponder(
    meta={
        "title": "All Employees",
        "description": "Meet the Team",
        "og:image": "asset:logo.png",
    }
)

Pre-loading data with startup_data

When a user navigates directly to a URL, any data your Form needs has to be fetched after it loads. With AppResponder, you can pre-load that data server-side and make it available at anvil.server.startup_data before the Form initialises, avoiding the extra round-trip.

In this example, we pre-load a list of employees from a Data Table and pass it to DirectoryForm via startup_data:

@anvil.server.route("/directory")
def serve_directory(**p):
    employees = app_tables.employees.search()
    
    responder = anvil.server.AppResponder(
        data={"employees": employees}, # pre-load startup_data with employees
        meta={
            "title": "All Employees",
            "description": "Meet the Team",
            "og:image": "asset:logo.png",
        }
    )
    return responder.load_form("DirectoryForm")

In DirectoryForm, read from startup_data if it’s available:

class DirectoryForm(DirectoryFormTemplate):
    def __init__(self, **properties):
        self.init_components(**properties)
        startup = anvil.server.startup_data or {}
        self.employees = startup.get("employees")

You can clone the example app from this guide and run it yourself:


Do you still have questions?

Our Community Forum is full of helpful information and Anvil experts.