Hello,
I am developing a custom app called custom_app for ERPNext and I have a requirement regarding the Home workspace.
My Requirements:
- After Installing the App (
custom_app):
- I want to replace the default ERPNext shortcuts in the Home workspace with my custom shortcuts (e.g., Active Customers, Active Suppliers, etc.).
- The default ERPNext shortcuts should be hidden or removed when my app is installed.
- After Uninstalling the App (
custom_app):
- I want the default ERPNext shortcuts to be restored, and my custom shortcuts should be removed.
What I’ve Tried:
- I’ve written a function to update the Home workspace and set custom shortcuts, but I am having trouble with hiding or removing the default shortcuts during installation and restoring them during uninstallation.
- I need help with the correct way to achieve this functionality and whether there are any hooks or methods I should use for this purpose.
Could anyone please help me with a solution or guide me on how to achieve this?
Hi @ashfaque
Got it — you basically want your custom_app to temporarily take over the “Home” workspace in ERPNext, then restore ERPNext’s defaults after uninstallation.
This is possible, but you’ll need to carefully hook into install and uninstall events and modify the Workspace document programmatically.
Here’s a step-by-step approach that works in ERPNext v15:
1. Understanding where “Home” workspace is stored
- Workspaces are DocTypes:
Workspace
- The Home workspace is usually a record with
name = "Home" (or Home-<module> if multi-language).
- The shortcuts are stored in the content JSON of that workspace (a list of blocks).
2. Plan
We’ll:
- On install: backup the original
Home workspace to a JSON file (in your app), then replace it with your custom layout.
- On uninstall: restore the original workspace from the backup.
3. Hooks
In custom_app/hooks.py:
python
after_install = "custom_app.setup.install"
before_uninstall = "custom_app.setup.uninstall"
4. Installer Script
In custom_app/setup.py:
python
import frappe
import json
import os
BACKUP_FILE = frappe.get_app_path("custom_app", "workspace_backup.json")
def install():
# Backup original Home workspace
try:
home_ws = frappe.get_doc("Workspace", "Home")
with open(BACKUP_FILE, "w") as f:
json.dump(home_ws.as_dict(), f, indent=2)
frappe.logger().info("Home workspace backed up.")
except frappe.DoesNotExistError:
frappe.logger().warning("Home workspace not found to backup.")
# Replace with custom workspace
replace_home_workspace()
def replace_home_workspace():
# Fetch or create Home workspace
try:
ws = frappe.get_doc("Workspace", "Home")
except frappe.DoesNotExistError:
ws = frappe.new_doc("Workspace")
ws.name = "Home"
ws.label = "Home"
# Clear existing content and set custom
ws.content = json.dumps([
{
"type": "shortcut",
"label": "Active Customers",
"link_to": "Customer",
"link_type": "DocType",
"filters": [["status", "=", "Active"]]
},
{
"type": "shortcut",
"label": "Active Suppliers",
"link_to": "Supplier",
"link_type": "DocType",
"filters": [["status", "=", "Active"]]
}
])
ws.save(ignore_permissions=True)
frappe.db.commit()
frappe.logger().info("Custom Home workspace set.")
def uninstall():
# Restore original Home workspace
if os.path.exists(BACKUP_FILE):
with open(BACKUP_FILE, "r") as f:
data = json.load(f)
if frappe.db.exists("Workspace", "Home"):
frappe.delete_doc("Workspace", "Home", ignore_permissions=True)
restored_ws = frappe.get_doc(data)
restored_ws.insert(ignore_permissions=True)
frappe.db.commit()
frappe.logger().info("Original Home workspace restored.")
else:
frappe.logger().warning("No backup found. Cannot restore.")
Notes & Gotchas
Workspace.content is a JSON string — ERPNext expects a very specific structure for shortcuts and cards. If you want your UI to look correct, copy a real workspace’s JSON and modify it.
- You must use
ignore_permissions=True since install/uninstall runs as a system process.
- If your ERPNext site is multilingual, “Home” might be
"Home-<lang>" (e.g., "Home-en"), so you may want to query frappe.get_all("Workspace", filters={"label": "Home"}) instead of hardcoding "Home".
- ERPNext caches workspaces, so you may need to run
frappe.clear_cache() after replacing/restoring.
add a new workspace and make it public by default and allow user roles then you can customze the whole workspace as you need no need to remove it
Excuse me, How can I add a new workspace in ERPNext version 15.
I go to workspace list and can’t see “Add new workspace” button
open any workspace and in the right bottom you will see this button

1 Like
I see it. Thank you so much.