diff --git a/docs/source/index.rst b/docs/source/index.rst
index 7b0e4af..04a2a56 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -15,6 +15,7 @@ Topics
slot.md
templates.md
context.md
+ namespace.md
preview.md
testing.md
articles.md
diff --git a/docs/source/namespace.md b/docs/source/namespace.md
new file mode 100644
index 0000000..0259175
--- /dev/null
+++ b/docs/source/namespace.md
@@ -0,0 +1,40 @@
+# NameSpace
+
+If your project has many components and want them to be organized in a better way, you can use the namespace feature.
+
+```bash
+├── components
+│ └── testapp # this is the namespace
+│ └── example
+│ ├── example.html
+│ └── example.py
+```
+
+```python
+from django_viewcomponent import component
+
+
+@component.register("testapp.example")
+class ExampleComponent(component.Component):
+
+ template_name = "testapp/example/example.html"
+
+ def __init__(self, **kwargs):
+ self.name = kwargs.get('name', 'World')
+```
+
+You can register the component as `testapp.example`
+
+```html
+{% load viewcomponent_tags %}
+
+{% component 'testapp.example' name="MichaelYin"%}
+{% endcomponent %}
+```
+
+To use the component in Django template, you can use `component 'testapp.example'`
+
+Notes:
+
+1. This can help keep the components organized.
+2. If you are developing 3-party Django package (`foo`), you can put all components in the `foo` namespace and use them in the package templates, this would not cause conflicts with other components in the project.
diff --git a/tests/test_tags.py b/tests/test_tags.py
index 421a096..7a4e339 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -1017,3 +1017,40 @@ def test_field_component_parameter(self):
test 4
"""
assert_dom_equal(expected, rendered)
+
+
+class TestNameSpace:
+ @pytest.fixture(autouse=True)
+ def register_component(self):
+ # auto discover components and register
+ from django_viewcomponent import autodiscover_components
+
+ autodiscover_components()
+
+ def test_component_namespace(self):
+ template = Template(
+ """
+ {% load viewcomponent_tags %}
+ {% component 'testapp.example' %}
+ {% endcomponent %}
+ """
+ )
+ rendered = template.render(Context({}))
+ expected = """
+ Hello, World!
+ """
+ assert_dom_equal(expected, rendered)
+
+ def test_component_namespace_with_parameters(self):
+ template = Template(
+ """
+ {% load viewcomponent_tags %}
+ {% component 'testapp.example' name="MichaelYin"%}
+ {% endcomponent %}
+ """
+ )
+ rendered = template.render(Context({}))
+ expected = """
+ Hello, MichaelYin!
+ """
+ assert_dom_equal(expected, rendered)
diff --git a/tests/testapp/components/testapp/example/example.html b/tests/testapp/components/testapp/example/example.html
new file mode 100644
index 0000000..0b1c541
--- /dev/null
+++ b/tests/testapp/components/testapp/example/example.html
@@ -0,0 +1 @@
+Hello, {{ self.name }}!
\ No newline at end of file
diff --git a/tests/testapp/components/testapp/example/example.py b/tests/testapp/components/testapp/example/example.py
new file mode 100644
index 0000000..f2616ff
--- /dev/null
+++ b/tests/testapp/components/testapp/example/example.py
@@ -0,0 +1,9 @@
+from django_viewcomponent import component
+
+
+@component.register("testapp.example")
+class ExampleComponent(component.Component):
+ template_name = "testapp/example/example.html"
+
+ def __init__(self, **kwargs):
+ self.name = kwargs.get("name", "World")