Skip to content

SEO compatible rendering #93

Closed
@Archmonger

Description

@Archmonger

Current Situation

Currently, sites built in IDOM are not SEO compatible. This is a fairly common issue with JavaScript frameworks such as ReactJS.

This might ultimately relate to persistent components (#34).

Proposed Actions

To resolve this, there needs to be an initial HTTP render, followed by a ReactPy re-render. The best way of doing this requires some form of persistent storage of all hook states, due to the fact that ASGI websockets are a completely different stack than HTTP rendering. Hook states will need to be stored server side in order to prevent spoofing. We likely have to use a database.

  1. Use the template tag to render the initial component as raw HTML
  2. Serialize all the component's hook values (probably through dill.pickle) and
    • This might need exposing some new hook APIs in core that provides returns hook values for a given component instance.
  3. Store serialized hook values within the database
    • Use the component's UUID as the database ID.
  4. When the JavaScript client requests it, rehydrate the components hook values
  5. Execute the ReactJS rendering
  6. Delete the component hook values from the database, as they are no longer needed.

The database model might look like this:

class IdomHookState(Model):
    uuid = models.UUIDField(
        primary_key=True, default=uuid.uuid4, editable=False, unique=True
    )
    hook_attributes = models.TextField()

This design brings up a challenge of determining when to evict old hook states (for example, if a user did the initial render but for some reason never performed a websocket connection). We don't want to store everything forever, so some configurable age-based eviction strategy might be needed. Expired entries should be culled before each fetch of IdomHookState.hook_attributes. Expiration should be based on last access time, which is fairly simple to do in Django like such: last_accessed = models.DateTimeField(auto_now=True).

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions