JavaScript Widget Embedding

Overview Description

The JavaScript Widget Embedding feature allows external websites to embed and display trend analysis data from the Naviplus platform. This feature uses a secure authentication mechanism via API keys and domain verification to ensure that only authorized websites can access specific datasets. The widgets are designed to be lightweight, responsive, and customizable to integrate seamlessly with the client's website design.

The API provides two main controllers:

  • EmbedWidgetController: Handles dataset listing, details, and histories
  • ProductAnalyzerController: Handles product analysis and review data

Activity Diagram

flowchart TD
    A[Client Website] -->|Embed Script Tag| B[Load Widget]
    B -->|Request with API Key| C{Validate Request}
    C -->|Invalid| D[Return Error]
    C -->|Valid| E[Route to Controller]
    E --> F{Controller Type}
    F -->|EmbedWidget| G[Dataset Operations]
    F -->|ProductAnalyzer| H[Product Analysis]
    G --> I[Return Dataset Data]
    H --> J[Return Analysis Data]
    I --> K[Render Widget]
    J --> K
    K --> L[Interactive Data Visualization]

API Endpoints

EmbedWidgetController Endpoints

Method Endpoint Description Parameters
GET /api/v1/widget/{slug} Get dataset list slug - Dataset identifier
GET /api/v1/widget/{slug}/{wldh_slug} Get dataset details slug, wldh_slug - Dataset and history identifiers
GET /api/v1/widget/{slug}/{wltg_slug}/histories Get dataset histories slug, wltg_slug - Dataset and group identifiers

ProductAnalyzerController Endpoints

Method Endpoint Description Parameters
GET /api/v1/widget/{slug}/{wldh_slug}/products Get base products slug, wldh_slug - Dataset and history identifiers
GET /api/v1/widget/{slug}/{wldh_slug}/products/similar-product Get similar products slug, wldh_slug - Dataset and history identifiers
GET /api/v1/widget/{slug}/{wldh_slug}/products/comparison Get product comparison table slug, wldh_slug - Dataset and history identifiers
GET /api/v1/widget/{slug}/{wldh_slug}/review/review-sentences Get review sentences slug, wldh_slug - Dataset and history identifiers
GET /api/v1/widget/{slug}/{wldh_slug}/review/review-chart Get review chart slug, wldh_slug - Dataset and history identifiers
GET /api/v1/widget/{slug}/{wldh_slug}/review/review-chart-by-viewpoint Get review chart by viewpoint slug, wldh_slug - Dataset and history identifiers
GET /api/v1/widget/{slug}/{wldh_slug}/sales/get-sales-chart Get sales trend chart slug, wldh_slug - Dataset and history identifiers

Case Documentation

Case 1: Successful Widget Embedding - Dataset Operations

Description

Client successfully embeds and displays dataset information widget on their website.

Sequence Diagram

sequenceDiagram
    participant Client as Client Website
    participant Widget as Widget Script
    participant API as EmbedWidgetController
    participant Auth as ValidateWidgetRequest
    participant Repo as EmbedJsWidgetRepository
    participant DataRepo as WishlistDatasetHistoryRepository
    participant DB as Database

    Note over Client,Widget: Step 1: Embed Script
    Client->>Widget: Include script tag with API key

    Note over Widget,API: Step 2: Initialize Widget
    Widget->>API: GET /api/v1/widget/{slug}
    
    Note over API,Auth: Step 3: Validate Request
    API->>Auth: Check API key & domain
    Auth->>Repo: findByApiKey(api_key)
    Repo->>DB: Query
    DB-->>Repo: Widget Data
    Repo-->>Auth: Widget Entity
    
    Note over Auth,DataRepo: Step 4: Validate Dataset
    Auth->>DataRepo: findBySlug(slug)
    DataRepo->>DB: Query
    DB-->>DataRepo: Dataset Data
    DataRepo-->>Auth: Dataset Entity
    Auth->>Auth: Check Group Permissions
    
    Note over Auth,API: Step 5: Request Authorized
    Auth-->>API: Request Authorized
    
    Note over API,Widget: Step 6: Return Data
    API-->>Widget: JSON Dataset Data
    
    Note over Widget,Client: Step 7: Render Widget
    Widget->>Client: Render Dataset Visualization

Steps

Step 1: Embed Script

  • Description: Client adds the widget script tag to their website
  • Implementation:
    <div class="widget-container">
      <tv-analysis-widget 
        id="id-widget"
        token="your_token" 
        slug="slug-name">
      </tv-analysis-widget>
    </div>
    <script type="module" src="https://trend-viewer.com/widget/widget.ce.js"></script>
    
  • Validation:
    • API key must be valid
    • Domain must be registered and allowed

Step 2: Initialize Widget

  • Description: Widget script initializes and prepares to load data
  • Action:
    • Creates widget container
    • Sets up styling and layout
    • Prepares HTTP request with headers

Step 3: Validate Request

  • Description: System validates the API key and domain
  • Validation:
    • API key existence check
    • Domain matching with registered domains
    • Widget status check (active/inactive)
    • Rate limiting based on domain and API key

Step 4: Validate Dataset

  • Description: System validates the requested dataset slug
  • Validation:
    • Dataset existence check
    • Group permissions check (widget's group must have access to dataset)
    • Dataset status check (active/inactive)

Step 5: Return Dataset Data

  • Description: System returns the requested dataset information
  • Response:
    • Success: 200 OK with JSON data
    • Error: Appropriate error code with message

Step 6: Render Widget

  • Description: Widget script renders the dataset visualization
  • Action:
    • Process received data
    • Generate charts and metrics
    • Apply custom styling if provided

Case 2: Product Analysis Widget

Description

Client successfully embeds and displays product analysis widget on their website.

Sequence Diagram

sequenceDiagram
    participant Client as Client Website
    participant Widget as Widget Script
    participant API as ProductAnalyzerController
    participant Auth as ValidateWidgetRequest
    participant Repo as EmbedJsWidgetRepository
    participant DataRepo as WishlistDatasetHistoryRepository
    participant DB as Database

    Note over Client,Widget: Step 1: Embed Script
    Client->>Widget: Include script tag with API key

    Note over Widget,API: Step 2: Initialize Widget
    Widget->>API: GET /api/v1/widget/{slug}/{wldh_slug}/products
    
    Note over API,Auth: Step 3: Validate Request
    API->>Auth: Check API key & domain
    Auth->>Repo: findByApiKey(api_key)
    Repo->>DB: Query
    DB-->>Repo: Widget Data
    Repo-->>Auth: Widget Entity
    
    Note over Auth,DataRepo: Step 4: Validate Dataset & History
    Auth->>DataRepo: findBySlug(slug)
    DataRepo->>DB: Query
    DB-->>DataRepo: Dataset Data
    DataRepo-->>Auth: Dataset Entity
    Auth->>Auth: Check Group Permissions
    
    Note over Auth,API: Step 5: Request Authorized
    Auth-->>API: Request Authorized
    
    Note over API,Widget: Step 6: Return Product Data
    API-->>Widget: JSON Product Analysis Data
    
    Note over Widget,Client: Step 7: Render Widget
    Widget->>Client: Render Product Analysis Visualization

Steps

Step 1-3: Same as Dataset Operations

Step 4: Validate Dataset & History

  • Description: System validates both dataset slug and history slug
  • Validation:
    • Dataset existence check
    • History record existence check
    • Group permissions check for both dataset and history
    • Status validation for both entities

Step 5: Return Product Analysis Data

  • Description: System returns product analysis information
  • Available endpoints:
    • Base products list
    • Similar products analysis
    • Product comparison table
    • Review sentences
    • Review charts (general, by viewpoint, sales trends)

Step 6: Render Product Analysis Widget

  • Description: Widget script renders product analysis visualization
  • Action:
    • Process product data
    • Generate comparison charts
    • Display review analytics
    • Show trend visualizations

Case 3: Unauthorized Access Attempt

Description

An unauthorized website attempts to use the widget with a valid API key.

Sequence Diagram

sequenceDiagram
    participant Client as Unauthorized Website
    participant Widget as Widget Script
    participant API as WidgetController
    participant Auth as ValidateWidgetRequest
    participant Repo as EmbedJsWidgetRepository

    Note over Client,Widget: Step 1: Embed Script
    Client->>Widget: Include script tag with API key

    Note over Widget,API: Step 2: Initialize Widget
    Widget->>API: GET /api/v1/widget/{slug}
    
    Note over API,Auth: Step 3: Validate Request
    API->>Auth: Check API key & domain
    Auth->>Repo: findByApiKey(api_key)
    Repo-->>Auth: Widget Entity
    
    Note over Auth,API: Step 4: Domain Validation Fails
    Auth->>Auth: Compare Origin domain with registered domain
    Auth-->>API: Domain not authorized (403)
    
    Note over API,Widget: Step 5: Return Error
    API-->>Widget: 403 Forbidden
    
    Note over Widget,Client: Step 6: Display Error
    Widget->>Client: Render Error Message

Steps

Step 1: Embed Script

  • Description: Unauthorized website adds the widget script tag
  • Action: Same as in successful case, but from unauthorized domain

Step 2: Initialize Widget

  • Description: Same as in successful case

Step 3: Validate Request

  • Description: System detects domain mismatch
  • Validation:
    • API key is valid
    • Domain does not match registered domain
    • Security warning is logged

Step 4: Return Error

  • Description: System returns authorization error
  • Response: 403 Forbidden with error message

Step 5: Display Error

  • Description: Widget displays error message
  • Action: Shows appropriate error message to end user

Database Related Tables & Fields

erDiagram
    EMBED_JS_WIDGETS {
        bigint id
        string name
        string domain
        string api_key
        bigint group_id
        enum status
        datetime created_at
        datetime updated_at
    }
    GROUPS {
        bigint id
        string name
        datetime created_at
        datetime updated_at
    }
    WISHLIST_DATASET_HISTORIES {
        bigint id
        string slug
        string name
        datetime created_at
        datetime updated_at
    }
    WISHLIST_TO_GROUPS {
        bigint wishlist_id
        bigint group_id
    }

    EMBED_JS_WIDGETS ||--o{ GROUPS : belongs_to
    WISHLIST_DATASET_HISTORIES ||--o{ WISHLIST_TO_GROUPS : has
    GROUPS ||--o{ WISHLIST_TO_GROUPS : has

Error Handling

  • Log

    • All access attempts are logged to security log
    • Invalid API keys and unauthorized domains are flagged
    • Rate limit violations are tracked
  • Error Detail:

    Status Code Error Message Description
    401 "Invalid API key" When API key is missing or invalid
    403 "Domain not authorized" When requesting domain is not registered
    403 "You do not have access to this dataset" When widget's group doesn't have access to the dataset
    404 "Dataset not found" When the requested dataset slug doesn't exist
    404 "Dataset history not found" When the requested history slug doesn't exist
    429 "Too many requests" When rate limit is exceeded

Additional Notes

  • Performance Considerations

    • Widget script is minified and compressed
    • Assets are served via CDN for faster loading
    • Data payloads are optimized for size
  • Security Measures

    • API keys should be treated as sensitive information
    • Domain validation prevents unauthorized embedding
    • Rate limiting prevents abuse
    • CORS headers are strictly configured
  • Future Enhancements

    • Support for custom theming via CSS variables
    • Interactive filtering options
    • Real-time data updates
    • Support for multiple datasets in a single widget