When building a multilingual Django application, choosing the right language for your users can make or break their experience. Instead of asking users to select a language every time, we can auto-detect it using domain names or subdomain prefixes.
In this article, you'll learn how to:
- Configure your Django app to support multiple languages.
- Set language based on domain (example.pl,example.com) or subdomain (pl.example.com,en.example.com).
- Keep everything clean and declarative — no messy if/elselogic.
This is a beginner-friendly guide. Let’s dive in.
📁 1. Project Setup and Language Configuration
Start by enabling multiple languages in your settings.py:
LANGUAGE_CODE = "en"
LANGUAGES = [
    ("en", "English"),
    ("pl", "Polish"),
]
You also need to add a fallback configuration:
USE_I18N = True
USE_L10N = True
USE_TZ = True
  
  
  🌐 2. Define Your Language Rules in settings.py
We'll store language-to-domain mappings in a declarative way:
LANGUAGE_BY_DOMAIN = {
    "whathappensnext.online": "en",
    "cobylodalej.online": "pl",
}
LANGUAGE_SUBDOMAIN_PREFIXES = {
    "en": "en",
    "pl": "pl",
}
USE_SUBDOMAIN_LANGUAGE = True  # Enable subdomain-based resolution
This way, you don’t need any if statements — all the logic is in settings.
⚖️ 3. Create the Language Detection Middleware
Now, let's build the middleware to read the host and determine the language:
from django.utils import translation
from django.conf import settings
def get_language_from_domain(host: str, fallback: str) -> str:
    domain = ".".join(host.lower().split(".")[-2:])
    return settings.LANGUAGE_BY_DOMAIN.get(domain, fallback)
def get_language_from_subdomain(host: str, fallback: str) -> str:
    parts = host.lower().split(".")
    if len(parts) < 3:
        return fallback
    return settings.LANGUAGE_SUBDOMAIN_PREFIXES.get(parts[0], fallback)
LANGUAGE_RESOLVERS = (
    get_language_from_domain,
    get_language_from_subdomain,
)
class SmartLanguageMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.fallback_language = getattr(settings, "LANGUAGE_CODE", "en")
    def __call__(self, request):
        host = request.get_host().split(":")[0]
        use_subdomain = getattr(settings, "USE_SUBDOMAIN_LANGUAGE", False)
        resolver = LANGUAGE_RESOLVERS[use_subdomain]
        lang = resolver(host, self.fallback_language)
        translation.activate(lang)
        request.LANGUAGE_CODE = lang
        response = self.get_response(request)
        translation.deactivate()
        return response
➕ 4. Register the Middleware
In your settings.py, add your new middleware before Django’s default locale middleware:
MIDDLEWARE = [
    "your_project.middleware.SmartLanguageMiddleware",
    "django.middleware.locale.LocaleMiddleware",
    ...
]
🪡 5. Example Use Cases
With this setup, users visiting:
- 
https://przykladowyserwis.comwill see Polish.
- 
https://someservice.comwill see English.
- 
https://pl.someservice.comwill see Polish (ifUSE_SUBDOMAIN_LANGUAGE = True).
- 
https://en.someservice.comwill see English.
You can always extend or modify the resolver logic to suit your needs.
🚀 6. Summary
By using a smart, declarative middleware, you:
- Detect languages based on host or subdomain automatically.
- Avoid hard-coded logic.
- Keep things clean and scalable.
This technique is great for multilingual SaaS apps or platforms where each region or market has its domain.
 
 
              
 
    
Top comments (0)