# Troubleshooting

## Disallowed MIME type error on Windows

Apparently Windows system-wide MIME type configuration sometimes won't load up JavaScript modules in certain browsers. The errors would be something like `Loading module from “http://127.0.0.1:8000/static/js/unicorn.js” was blocked because of a disallowed MIME type (“text/plain”)` or `Failed to load module script: The server responded with a non-JavaScript MIME type of "text/plain".`

One suggested solution is to add the following to the bottom of the settings file:

```python
# settings.py

if DEBUG:
    import mimetypes
    mimetypes.add_type("application/javascript", ".js", True)
```

See this [Windows MIME type detection pitfalls](https://www.taricorp.net/2020/windows-mime-pitfalls/) article, this [StackOverflow answer](https://stackoverflow.com/a/16355034), or [issue #201](https://github.com/adamghill/django-unicorn/issues/201) for more details.

## Components not working on public pages with LoginRequiredMiddleware

Django 5.1 introduced
[`LoginRequiredMiddleware`](https://docs.djangoproject.com/en/stable/ref/middleware/#django.contrib.auth.middleware.LoginRequiredMiddleware)
which redirects every unauthenticated request to the login page by default.
Because Unicorn communicates via AJAX, an unauthenticated user on a public page
will see a token or parse error in the browser console (the endpoint received a
redirect instead of the expected JSON response).

**Fix: mark the component as public via `Meta.login_not_required = True`.**

```python
# newsletter_signup.py
from django_unicorn.components import UnicornView

class NewsletterSignupView(UnicornView):
    email = ""

    class Meta:
        login_not_required = True  # allow unauthenticated users

    def subscribe(self):
        ...
```

Unicorn checks this flag at request time and returns a `401` JSON response
(instead of a redirect) for any component that does *not* set
`Meta.login_not_required = True` when the middleware is active and the user is not
authenticated. Components that require login can omit the `Meta` flag entirely and
rely on the default protected behaviour.

```{note}
`Meta.login_not_required` has no effect on Django versions older than 5.1 because
`LoginRequiredMiddleware` was not available before that release.
```

## Missing CSRF token or 403 Forbidden errors

`Unicorn` uses CSRF to protect its endpoint from malicious actors. The two parts that are required for CSRF are `"django.middleware.csrf.CsrfViewMiddleware"` in `MIDDLEWARE` and `{% csrf_token %}` in the template that includes any `Unicorn` components.

```python
# settings.py

...
MIDDLEWARE = [
    ...
    "django.middleware.csrf.CsrfViewMiddleware",
    ...
]
```

```html
<!-- template.html -->
{% load unicorn %}

<html>
  <head>
    {% unicorn_scripts %}
  </head>
  <body>
    {% csrf_token %}

    {% unicorn 'hello-world' %}
  </body>
</html>
```

## Tables and invalid HTML

Browsers are very strict about table structure (e.g. `<tr>` can only be a direct child of `<tbody>`, `<thead>`, `<tfoot>`, or `<table>`, and `<div>` is not allowed as a direct child of `<tr>`). If you have a component that renders a table row, unexpected behavior can occur because the browser will "foster parent" invalid elements out of the table structure before `Unicorn` can seemingly react to them.

For example, this valid-looking component template will cause issues:

```html
<!-- invalid-table-row.html -->
<tr>
  <td>{{ name }}</td>
  {% if show_modal %}
    <div class="modal">...</div>
  {% endif %}
</tr>
```

The browser will move the `div` out of the `tr` (and likely out of the `table` entirely), so when `Unicorn` tries to update the component, it will be confused by the missing element.

To fix this, ensure that all content is inside a valid table element, like a `td`:

```html
<!-- valid-table-row.html -->
<tr>
  <td>{{ name }}</td>
  <td>
    {% if show_modal %}
      <div class="modal">...</div>
    {% endif %}
  </td>
</tr>
```

