ownCloud Web with Custom Theming

Introduction

Just like with other clients (Desktop, Android, iOS), themes can be used with ownCloud Web. As an organization or company you may be interested in theming the ownCloud web user interface with your brand and slogan, while playful private individuals may simply enjoy the fun of decorating ownCloud web the way they like.

This can be achieved by providing a json file that contains text snippets (like brand name and slogan), paths to images (e.g. logos or favicon) and design tokens for various parameters like color, sizing and spacing. In the following, we explain the setup and configuration options and provide an empty template for you to get started.

owncloud web can be seen as a hub for extensions like the files extension, the user management extension and others. The central part of owncloud web with respect to theming is the web-runtime which holds all general style definitions which can be used by but also be individually set by an extension. This makes it possible to e.g. individually style the generally frame independently from an extension.

Providing a Theme

Your theming configuration resides in a .json file, e.g. theme.json. To load this file, it needs to be correctly referenced inside your config/config.json. Alternatively, when using Infinite Scale, you can define the theming json file via the WEB_UI_THEME_PATH environment variable which takes precedence over the theming file reference in config.json, if any is set. An example configurations can be found on GitHub.

If no theme is provided or the loading of your custom theme fails, the standard ownCloud theme will be loaded as a fallback. However, this doesn’t stop you from correctly loading a theme that is wrongly formatted, so please read the instructions below carefully.

To reference your theme, you have two options:

  • Using a URL like:

    "theme": "https://externalurl.example.com/theme-name/theme.json",

    To avoid CORS issues, make sure that you host the URL on the same domain as your ownCloud web hosting.

  • For development and testing purposes, you can store your theme.json inside packages/web-runtime/themes/{theme-name}/ and reference it in the config.json file. However, this is not recommended for production use since your changes may get lost when updating Infinite Scale or the Web app on ownCloud Server.

Configuring a Theme

Inside your theme.json file, you can provide multiple themes as first-level objects. Currently, only the one called "default" gets applied when the frontend application is started.

Feel free to use the snippet below as a base for writing your own theme. Replace the strings and image file paths accordingly. Also, make sure to delete the comments from the file.

{
  "default": {
    "general": {
      "name": "ownCloud",
      "slogan": "ownCloud – A safe home for all your data"
    },
    "logo": {
      "topbar": "https://externalurl.example.com/url/for/remote/theme/assets/logo.svg",
      "favicon": "https://externalurl.example.com/url/for/remote/theme/assets/favicon.jpg",
      "login": "relative/path/for/local/theme/logo.svg"
    },
    "loginPage": {
      "autoRedirect": true,
      "backgroundImg": "relative/path/for/local/theme/background.jpg"
    },
    "designTokens": {}
  },
  "alternative": {},
  "dark": {}
}

See below for the meaning of all the first-level objects inside a single theme and recommendations on how to make best use of them.

"general"

Here, you can specify a "name" and a "slogan" string. The name gets used in the HTML page <title>, and both of them are shown on various screens like: login, loading, error and public share pages.

Here, you can specify the images to be used in the "topbar", for the "favicon" and on the "login" page. Various formats are supported and it’s up to you to decide which one fits best to your use case.

"loginPage"

Using the "autoRedirect" boolean, you can specify whether the user is shown a login page before possibly getting redirected to your LDAP/OIDC/OAuth provider. If it is set to true, you can specify the background image for the login page by providing an image file in the "backgroundImg" option.

"designTokens"

To further customize your ownCloud instance, you can provide your own styles. To give you an idea of how a working design system looks, feel free to head over to the ownCloud design tokens for inspiration.

All the variables are initialized using the ownCloud design tokens and then overwritten by your theme variables. Therefore, you don’t have to provide all the variables and can use the default ownCloud colors as a fallback.

In general, the theme loader looks for a designTokens key inside your theme configuration. Inside the designTokens, it expects to find a collection of colorPalette, fontSizes and spacing. The structure is outlined below:

{
  "default": {
    "general": {},
    "designTokens": {
      "breakpoints": {},
      "colorPalette": {},
      "fontSizes": {},
      "sizes": {},
      "spacing": {}
    }
  }
}

Follow this structure to make sure your theming configuration is loaded correctly.

Extendability

If you define different key-value pairs inside any of the objects in "designTokens", they will get loaded and initialized as CSS custom properties but don’t take any effect in the user interface. This gives you the opportunity to customize extension styles from within the theme in the web-runtime, without the need redefining the same style components in an extension again. Note that you can overwrite a style component set the web-runtime for an extension by the extension.

Breakpoints

If you’d like to set different breakpoints than the default ones in the ownCloud design system, you can set them using theming variables.

Breakpoint variables get prepended with --oc-breakpoint-.
Example: “large-default” creates the custom CSS property --oc-breakpoint-large-default.

{
  "breakpoints": {
    "xsmall-max": "",
    "small-default": "",
    "small-max": "",
    "medium-default": "",
    "medium-max": "",
    "large-default": "",
    "large-max": "",
    "xlarge": ""
  }
}

Colors

For the color values, you can use any valid CSS color format, like hex (#fff), rgb (rgb(255,255,255)) or color names (white).

Color variables get prepended with --oc-color-.
Example: “background-default” creates the custom CSS property --oc-color-background-default.

Again, you can use the ownCloud design tokens as a reference implementation:

{
  "colorPalette": {
    "background-accentuate": "",
    "background-default": "",
    "background-highlight": "",
    "background-muted": "",
    "border": "",
    "input-bg": "",
    "input-border": "",
    "input-text-default": "",
    "input-text-muted": "",
    "swatch-brand-default": "",
    "swatch-brand-hover": "",
    "swatch-danger-default": "",
    "swatch-danger-hover": "",
    "swatch-danger-muted": "",
    "swatch-inverse-default": "",
    "swatch-inverse-hover": "",
    "swatch-inverse-muted": "",
    "swatch-passive-default": "",
    "swatch-passive-hover": "",
    "swatch-passive-muted": "",
    "swatch-primary-default": "",
    "swatch-primary-hover": "",
    "swatch-primary-muted": "",
    "swatch-primary-gradient": "",
    "swatch-success-default": "",
    "swatch-success-hover": "",
    "swatch-success-muted": "",
    "swatch-warning-default": "",
    "swatch-warning-hover": "",
    "swatch-warning-muted": "",
    "text-default": "",
    "text-inverse": "",
    "text-muted": ""
  }
}

Font Sizes

You can change the default, large and medium font sizes according to your needs. If you need more customization options regarding font sizes, open an issue on GitHub with a detailed description.

Font size variables get prepended with --oc-font-size-.
Example: “default” creates the custom CSS property --oc-font-size-default.

{
  "fontSizes": {
    "default": "",
    "large": "",
    "medium": ""
  }
}

Sizes

Use sizing variables to change various UI elements, such as icon and logo appearance, table row or checkbox sizes, according to your needs. If you need more customization options regarding sizes, open an issue on GitHub a detailed description.

Size variables get prepended with --oc-size-.
Example: “icon-default” creates the custom CSS property --oc-size-icon-default.

{
  "sizes": {
    "form-check-default": "",
    "height-small": "",
    "height-table-row": "",
    "icon-default": "",
    "max-height-logo": "",
    "max-width-logo": "",
    "width-medium": ""
  }
}

Spacing

Use the six spacing options
(xsmall | small | medium | large | xlarge | xxlarge)
to create a more (or less) condensed version of the user interface. If you need more customization options regarding spacing, open an issue on GitHub with a detailed description.

Spacing variables get prepended with --oc-space-.
Example: “xlarge” creates the custom CSS property --oc-space-xlarge.

{
  "spacing": {
    "xsmall": "",
    "small": "",
    "medium": "",
    "large": "",
    "xlarge": "",
    "xxlarge": ""
  }
}

Example Theme

An empty template for your custom theme is provided below. Use the instructions above to set it up according to your needs.

Since changing themes at runtime is not yet supported, it only consists of a default theme.
{
  "default": {
    "general": {
      "name": "",
      "slogan": ""
    },
    "logo": {
      "topbar": "",
      "favicon": "",
      "login": "",
      "notFound": ""
    },
    "loginPage": {
      "autoRedirect": true,
      "backgroundImg": ""
    },
    "designTokens": {
      "breakpoints": {
        "xsmall-max": "",
        "small-default": "",
        "small-max": "",
        "medium-default": "",
        "medium-max": "",
        "large-default": "",
        "large-max": "",
        "xlarge": ""
      },
      "colorPalette": {
        "background-accentuate": "",
        "background-default": "",
        "background-highlight": "",
        "background-muted": "",
        "border": "",
        "input-bg": "",
        "input-border": "",
        "input-text-default": "",
        "input-text-muted": "",
        "swatch-brand-default": "",
        "swatch-brand-hover": "",
        "swatch-danger-default": "",
        "swatch-danger-hover": "",
        "swatch-danger-muted": "",
        "swatch-inverse-default": "",
        "swatch-inverse-hover": "",
        "swatch-inverse-muted": "",
        "swatch-passive-default": "",
        "swatch-passive-hover": "",
        "swatch-passive-muted": "",
        "swatch-primary-default": "",
        "swatch-primary-hover": "",
        "swatch-primary-muted": "",
        "swatch-primary-gradient": "",
        "swatch-success-default": "",
        "swatch-success-hover": "",
        "swatch-success-muted": "",
        "swatch-warning-default": "",
        "swatch-warning-hover": "",
        "swatch-warning-muted": "",
        "text-default": "",
        "text-inverse": "",
        "text-muted": ""
      },
      "fontSizes": {
        "default": "",
        "large": "",
        "medium": ""
      },
      "sizes": {
        "form-check-default": "",
        "height-small": "",
        "height-table-row": "",
        "icon-default": "",
        "max-height-logo": "",
        "max-width-logo": "",
        "width-medium": ""
      },
      "spacing": {
        "xsmall": "",
        "small": "",
        "medium": "",
        "large": "",
        "xlarge": "",
        "xxlarge": ""
      }
    }
  }
}