Introduction: What Is Portal Development in Frappe?
Portal development in Frappe Framework v15 allows you to expose selected ERPNext or Frappe data securely to external users such as customers, suppliers, or partners through the website.
Portals are role-based, permission-controlled, and built using the Website module, without exposing Desk access.
This approach is commonly used for:
- Customer portals
- Supplier portals
- Student or member dashboards
- Self-service ERP access
Who Should Use This Guide?
Target Audience
- ERPNext Developers
- Frappe Framework Developers
- ERPNext Implementation Consultants
- Technical Architects
Technical Prerequisites
- Frappe Framework v15
- Bench-based site
- Basic knowledge of DocTypes and permissions
- Website module enabled
How Portal Architecture Works in Frappe v15
In Frappe v15, portals are built using a combination of:
- Website routes
- Portal roles
- DocType permissions
- Jinja templates
- Whitelisted server methods
Key components involved:
| Component | Purpose |
| Website Module | Renders portal pages |
| Portal Roles | Restrict access |
| DocType Permissions | Control data visibility |
| Context Variables | Pass data to templates |
How to Enable Portal Access for Users
Answer: Portal access is enabled by assigning a portal role to a user.
Steps:
- Go to User
- Enable User Type = Website User
- Assign a role such as:
- Customer
- Supplier
- Custom Portal Role
- Save the user
Once assigned, the user can log in via /login and access portal pages.
How to Create a Portal Page in Frappe v15
Method 1: Using Website Route
Create a Python file inside your app:
your_app/www/my-portal-page.py
import frappe
def get_context(context):
context.no_cache = 1
context.title = "My Portal Page"
context.user = frappe.session.user
Create the corresponding HTML file:
your_app/www/my-portal-page.html
<h2>Welcome {{ user }}</h2>
<p>This is a portal page.</p>
Access it at:
/my-portal-page
How to Restrict Portal Pages to Logged-In Users
Answer: Use frappe.session.user to validate access.
Example:
import frappe
def get_context(context):
if frappe.session.user == "Guest":
frappe.throw("You must be logged in to access this page")
This ensures only authenticated users can access the page.
How to Display DocType Data on a Portal Page
You can safely fetch data using frappe.get_all() with permission checks.
Example:
def get_context(context):
context.invoices = frappe.get_all(
"Sales Invoice",
filters={"customer": frappe.session.user},
fields=["name", "posting_date", "grand_total"]
)
HTML:
<ul>
{% for inv in invoices %}
<li>{{ inv.name }} – {{ inv.grand_total }}</li>
{% endfor %}
</ul>
Frappe automatically enforces permission rules.
How Portal Permissions Work in Frappe v15
Portal visibility depends on DocType Permission Rules.
Key points:
- Portal users never access Desk
- Permissions must include:
- Read
- If Owner
- Role must be assigned to Website User
Example configuration:
- DocType: Sales Invoice
- Role: Customer
- Permission: Read
- Condition: If Owner
How to Use get_context() Properly
Answer: get_context() prepares all data before rendering the page.
Best practices:
- Avoid heavy queries
- Use filters
- Never bypass permissions
- Use frappe.get_all() instead of SQL
How to Add Portal Navigation Links
Use portal_menu_items in hooks.py:
portal_menu_items = [
{"title": "My Invoices", "route": "/my-invoices"}
]
This adds links to the portal navbar.
Security Best Practices for Portal Development
- Never use raw SQL
- Never expose internal fields
- Always respect permission rules
- Validate session user
- Avoid whitelisting methods unnecessarily
Common Portal Use Cases in ERPNext
- Customer invoice tracking
- Supplier purchase order status
- Service ticket portals
- Membership dashboards
- Student portals
Troubleshooting Common Portal Issues
Portal page shows blank
- Check route file name
- Ensure HTML file exists
User sees permission error
- Verify role assignment
- Check DocType permissions
Data not loading
- Confirm filters match logged-in user
Advanced Topic: Portal vs Desk Access
| Feature | Portal | Desk |
| UI | Website | App |
| Security | Role-based | Full permissions |
| Customization | High | Moderate |
| Intended Users | External | Internal |
Related Resources
Official Docs: https://docs.frappe.io/framework/user/en/guides/portal-development
GitHub v15: https://github.com/frappe/frappe/tree/version-15
Final Thoughts
Portal development in Frappe Framework v15 is a powerful way to expose ERP functionality securely without giving full system access.
By using official APIs, permission controls, and website routes, you can build scalable, secure, and user-friendly portals aligned with ERPNext best practices.