Skip to content

Support swagger-ui translations #24

Description

@dblock

For the current version, translation support should be split into two layers:

  1. translation of wrapper-owned UI in this gem
  2. optional extension points for deeper Swagger UI component overrides

The recommended first implementation is to support only the UI text owned by grape-swagger-rails itself and explicitly avoid promising full upstream Swagger UI localization.

Why

The current codebase vendors Swagger UI 5.32.5, but Swagger UI does not appear to expose a stable, officially documented localization API suitable for this gem to depend on.

Relevant upstream context:

Because of that, built-in “full translation support” would require this gem to own a fragile override layer tied to Swagger UI internals.

Recommended Scope

Phase 1: Translate wrapper-owned UI

Add translation support only for text rendered or controlled directly by grape-swagger-rails, for example:

  • theme toggle label
  • spec selector label
  • API key input placeholder or label when controlled by the wrapper
  • page title fallback such as Swagger

This is low-risk and fully under local control.

Phase 2: Expose extension points for deeper Swagger UI overrides

Do not attempt to fully localize all upstream Swagger UI text out of the box.

Instead:

  • keep built-in translation support limited to wrapper UI
  • document how advanced users can inject Swagger UI plugins through swagger_ui_config
  • optionally provide a minimal plugin hook for targeted component overrides later

Proposed API

Suggested options:

GrapeSwaggerRails.options.locale = :en

GrapeSwaggerRails.options.translations = {
  en: {
    theme_toggle_dark: 'Dark Mode',
    theme_toggle_light: 'Light Mode',
    spec_selector: 'Specification',
    api_key_placeholder: 'api_key',
    page_title: 'Swagger'
  },
  fr: {
    theme_toggle_dark: 'Mode sombre',
    theme_toggle_light: 'Mode clair',
    spec_selector: 'Spécification',
    api_key_placeholder: 'clé_api',
    page_title: 'Swagger'
  }
}

Optional request-time locale resolution:

GrapeSwaggerRails.options.locale_resolver = ->(request) { I18n.locale }

This is preferable to a Rails-I18n-only design because:

  • it keeps the gem self-contained
  • it works in simpler host apps
  • it allows a later Rails-I18n fallback without breaking the public API

Implementation Shape

Ruby options

Add new options:

  • locale
  • locale_resolver
  • translations

Controller/helper layer

Resolve the active locale per request and serialize the active translation dictionary into HTML data-* attributes.

Example helper payload:

{
  swagger_options: options.marshal_dump.to_json,
  swagger_locale: resolved_locale,
  swagger_translations: resolved_translations.to_json
}

Frontend layer

In frontend/grape_swagger_rails/index.ts:

  • read swaggerTranslations from document.documentElement.dataset
  • add a small translation helper

Example:

function t(key: string, fallback: string): string {
  return translations[key] || fallback;
}

Use it only for wrapper-owned UI:

  • theme toggle label
  • spec selector label
  • placeholders
  • title fallback when needed

Deeper Swagger UI Localization

If deeper localization is needed later, build it as an extension point rather than a blanket built-in feature.

The repo already supports:

GrapeSwaggerRails.options.swagger_ui_config = {
  plugins: [ ... ]
}

The practical next step would be to document how host applications can inject Swagger UI plugins that override selected React components.

If the gem itself eventually provides built-in localized component overrides, keep that list intentionally small and limited to stable surfaces.

Possible candidates:

  • InfoContainer
  • auth-related labels if stable override points exist
  • selected top-level headings

What to Avoid

  • Do not patch or rewrite vendored swagger-ui-bundle.js for translation purposes.
  • Do not promise full localization support in the README unless the gem actually maintains a tested override layer across Swagger UI upgrades.
  • Do not couple the design only to Rails I18n.t; keep Rails I18n optional.

Recommended Rollout

  1. Add wrapper-level translation support only.
  2. Document that internal Swagger UI strings remain upstream-controlled.
  3. Document the existing swagger_ui_config plugin escape hatch for advanced customization.
  4. Consider a small built-in localized component override layer only if there is demonstrated demand.

Suggested README Wording

grape-swagger-rails supports translation of the wrapper UI it owns (page chrome, labels, toggles, placeholders).
Internal Swagger UI text is controlled by upstream Swagger UI and is not fully localized by this gem.
Advanced users can inject Swagger UI plugins via swagger_ui_config to override additional components.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions