---
title: "Hooks"
space: "Frappe Framework"
url: "https://www.prilk.com/nl/docs/frappe-framework/hooks"
updated: "2026-05-14"
---

## Hooks

Hooks laten een app Frappe en andere apps uitbreiden zonder hun code te forken. Elke app declareert hooks in `hooks.py`. Deze pagina dekt zowel het concept als de volledige referentie.

### Waarom hooks
Frappes filosofie: **uitbreiden, niet forken**. Wilt u reageren op een ingediende Verkoopfactuur — wijzig dan ERPNext niet. Schrijf een hook in uw eigen app. Updates van ERPNext botsen niet met uw code, en uw aanpassing overleeft elke upgrade.

### Hoe hooks worden uitgevoerd
Meerdere apps kunnen dezelfde event hooken. Frappe draait ze in install-volgorde. Geen blokkeert de ander — tenzij er een exception is, dan abort de operatie voor allemaal. Ontwerp uw hooks idempotent (veilig opnieuw te draaien) en licht.

---

## Referentie: alle beschikbare hooks

### Installatie-lifecycle

```python
before_install = "my_app.install.before_install"
after_install = "my_app.install.after_install"
after_migrate = "my_app.install.after_migrate"
before_uninstall = "my_app.install.before_uninstall"
after_uninstall = "my_app.install.after_uninstall"
```

### Document-events

```python
doc_events = {
    "Sales Invoice": {
        "validate": "my_app.custom.sales_invoice.validate",
        "before_save": "my_app.custom.sales_invoice.before_save",
        "on_update": "my_app.custom.sales_invoice.on_update",
        "before_submit": "my_app.custom.sales_invoice.before_submit",
        "on_submit": "my_app.custom.sales_invoice.on_submit",
        "before_cancel": "my_app.custom.sales_invoice.before_cancel",
        "on_cancel": "my_app.custom.sales_invoice.on_cancel",
        "on_trash": "my_app.custom.sales_invoice.on_trash",
    },
    "*": {
        "on_update": "my_app.audit.log_change",  # spaarzaam — vuurt op elk DocType
    }
}
```

### Scheduler

```python
scheduler_events = {
    "all": ["my_app.tasks.all"],              # Elke minuut
    "hourly": ["my_app.tasks.hourly"],
    "daily": ["my_app.tasks.daily"],
    "weekly": ["my_app.tasks.weekly"],
    "monthly": ["my_app.tasks.monthly"],
    "cron": {
        "0 9 * * 1-5": ["my_app.tasks.weekday_morning"]
    }
}
```

### Permissies

```python
permission_query_conditions = {
    "Sales Invoice": "my_app.permissions.sales_invoice_query",
}
has_permission = {
    "Sales Invoice": "my_app.permissions.sales_invoice_has_permission",
}
```

### DocType override

```python
override_doctype_class = {
    "Sales Invoice": "my_app.overrides.CustomSalesInvoice"
}
```

### UI inclusion

```python
app_include_js = "my_app.bundle.js"               # Alleen desk
app_include_css = "my_app.bundle.css"
web_include_js = "my_portal.bundle.js"            # Alleen portal
web_include_css = "my_portal.bundle.css"

doctype_js = {
    "Customer": "public/js/customer.js"
}
doctype_list_js = {
    "Sales Invoice": "public/js/sales_invoice_list.js"
}
```

### Routing & website

```python
website_route_rules = [
    {"from_route": "/orders/<name>", "to_route": "order-detail"},
]
update_website_context = ["my_app.context.update_context"]
```

### Fixtures

```python
fixtures = [
    {"dt": "Role", "filters": [["name", "in", ["My Custom Role"]]]},
    {"dt": "Custom Field", "filters": [["dt", "in", ["Customer", "Supplier"]]]},
]
```

### Whitelisted methods

```python
override_whitelisted_methods = {
    "frappe.client.get_count": "my_app.custom.get_count"
}
```

### Boot-sessie

```python
boot_session = "my_app.boot.boot_session"        # Voeg data toe aan frappe.boot
```

---

Voor canonieke updates en eventuele nieuwere hooks: [frappeframework.com/docs/v15/user/en/python-api/hooks](https://frappeframework.com/docs/v15/user/en/python-api/hooks).
