github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/docs/client-app-dev.md (about)

     1  [Table of contents](README.md#table-of-contents)
     2  
     3  # Develop a client-side application
     4  
     5  ## Using `cozy-app-dev`
     6  
     7  This document describe a tool to run an environment in order to develop
     8  client-side application on the cozy-stack.
     9  
    10  We provide two different ways to run this environment, either manually where you
    11  have to install part of the dependencies yourself or _via_ a Docker image in
    12  which all dependencies are packed.
    13  
    14  This environment will provide a running instance a http server serving both a
    15  specified directory of your application on `app.cozy.localhost:8080` and the
    16  `cozy-stack` on `cozy.localhost:8080` (you can change the hostname and port if you
    17  want, see below).
    18  
    19  The default passphrase will be "cozy"
    20  
    21  ### Manually
    22  
    23  To run the `scripts/cozy-app-dev.sh` directly on you system, you'll need to
    24  following dependencies:
    25  
    26  -   `go`
    27  -   `curl`
    28  -   `git`
    29  -   `couchdb2`: you need at least a running instance of CouchDB 2
    30  
    31  Examples:
    32  
    33  ```sh
    34  $ ./scripts/cozy-app-dev.sh -d ~/code/myapp
    35  ```
    36  
    37  If your CouchDB 2 instance is not running on `localhost:5984`, you can specify
    38  another host and port with the variable `COUCHDB_URL` like so:
    39  
    40  ```sh
    41  $ COUCHDB_URL=http://couchdb.local:1234/ ./scripts/cozy-app-dev.sh -d ~/code/myapp
    42  ```
    43  
    44  You can have more informations about the usage of this script with the following
    45  command:
    46  
    47  ```
    48  $ ./scripts/cozy-app-dev.sh -h
    49  ```
    50  
    51  ### With Docker
    52  
    53  If you do not want to install the required dependencies, we provide a Docker
    54  image which encapsulates the dev script and all its dependencies.
    55  
    56  To download the latest version, you can run this command:
    57  
    58  ```sh
    59  docker pull cozy/cozy-app-dev
    60  ```
    61  
    62  If you work behind a corporate proxy, and Docker is configured to inject proxy
    63  configuration into the containers, you need to ensure that both `localhost` and
    64  `cozy.localhost` are configured not to use the proxy. Following is the minimal
    65  `~/.docker/config.json` configuration that has been shown to work:
    66  
    67  ```json
    68  {
    69      "proxies": {
    70          "default": {
    71              "httpProxy": "MY_CORPORATE_PROXY",
    72              "httpsProxy": "MY_CORPORATE_PROXY",
    73              "noProxy": "localhost,cozy.localhost"
    74          }
    75      }
    76  }
    77  ```
    78  
    79  To run a ephemeral instance, on the `$HOME/myapp` directory, use the following
    80  command (warning: all the data stored by your application in couchdb and the VFS
    81  won't remain after):
    82  
    83  ```sh
    84  $ docker run --rm -it \
    85      -p 8080:8080 \
    86      -p 8025:8025 \
    87      -v "$HOME/myapp":/data/cozy-app \
    88      cozy/cozy-app-dev
    89  ```
    90  
    91  To keep your data even when stopping the container, run the following command:
    92  
    93  ```sh
    94  $ docker run --rm -it \
    95      -p 8080:8080 \
    96      -p 8025:8025 \
    97      -v "$HOME/myapp":/data/cozy-app \
    98      -v "$(pwd)/db":/usr/local/couchdb/data \
    99      -v "$(pwd)/storage":/data/cozy-storage \
   100      cozy/cozy-app-dev
   101  ```
   102  
   103  You can mount your yaml config file, to change the log level for example:
   104  
   105  ```sh
   106  $ docker run --rm -it \
   107      -p 8080:8080 \
   108      -p 8025:8025 \
   109      -v "$HOME/myapp":/data/cozy-app \
   110      -v "$HOME/cozy.yaml":/etc/cozy/cozy.yaml \
   111      cozy/cozy-app-dev
   112  ```
   113  
   114  A [MailHog](https://github.com/mailhog/MailHog) is running inside docker to
   115  catch emails. You can view the emails sent by the stack in a web interface on
   116  http://cozy.localhost:8025/
   117  
   118  You can also expose the couchdb port (listening in the container on 5984) in
   119  order to access its admin page. For instance add `-p 1234:5984` to access to the
   120  admin interface on `http://localhost:1234/_utils`.
   121  
   122  Make sure you application is built into `$HOME/myapp` (it should have an
   123  `index.html` and a `manifest.webapp` files), otherwise it will not work. As an
   124  example, for the [Drive application](https://github.com/cozy/cozy-drive/), it
   125  should be `$HOME/drive/build`.
   126  
   127  If you want to use several applications (for testing the intents for example),
   128  you can mount several directories inside `/data/cozy-app` like this:
   129  
   130  ```sh
   131  $ docker run --rm -it \
   132      -p 8080:8080 \
   133      -p 8025:8025 \
   134      -v "$HOME/appone":/data/cozy-app/appone \
   135      -v "$HOME/apptwo":/data/cozy-app/apptwo \
   136      cozy/cozy-app-dev
   137  ```
   138  
   139  ## Good practices for your application
   140  
   141  When an application makes a request to the stack, like loading a list of
   142  contacts, it sends two informations that will be used by the stack to allow or
   143  deny the access:
   144  
   145  -   the user session cookie
   146  -   a token that identifies the application (only when the user is connected).
   147  
   148  So, the application needs such a token. It also needs to know where to send the
   149  requests for the stack (it can be guessed, but with the nested vs flat
   150  subdomains structures, it's better to get the information from the stack). To do
   151  that, when the application loads its HTML index file, the stack will parse it as
   152  a template and will insert the relevant values. The configuration can be injected
   153  as a JSON with `{{.CozyData}}`.
   154  
   155  If you need more control or have some compatibility issues, it is possible to
   156  inject the individual values with:
   157  
   158  -   `{{.Token}}` will be replaced by the token for the application.
   159  -   `{{.Domain}}` will be replaced by the stack hostname.
   160  -   `{{.Locale}}` will be replaced by the locale for the instance.
   161  -   `{{.AppName}}`: will be replaced by the application name.
   162  -   `{{.AppSlug}}`: will be replaced by the application slug.
   163  -   `{{.AppNamePrefix}}`: will be replaced by the application name prefix.
   164  -   `{{.AppEditor}}`: will be replaced by the application's editor.
   165  -   `{{.IconPath}}`: will be replaced by the application's icon path.
   166  -   `{{.SubDomain}}` will be replaced by `flat` or `nested`.
   167  -   `{{.Tracking}}` will be replaced by a value to indicate if tracking is
   168      enabled.
   169  -   `{{.Capabilities}}` will be replaced by JSON with the
   170      [capabilities](./settings.md#get-settingscapabilities).
   171  -   `{{.Flags}}` will be replaced by JSON with the
   172      [feature flags](./settings.md#feature-flags).
   173  
   174  There are also some helpers to inject asset tags or URLs:
   175  
   176  -   `{{.CozyBar}}` will be replaced by the JavaScript to inject the cozy-bar.
   177  -   `{{.CozyClientJS}}` will be replaced by the JavaScript to inject the
   178      cozy-client-js.
   179  -   `{{.CozyFonts}}` will be replaced by the `fonts.css` used to inject the
   180      web fonts (Lato and Lato bold by default).
   181  -   `{{.ThemeCSS}}` will be replaced by the `theme.css`. It is empty by default,
   182      but can be overrided by using `contexts`. See
   183      [contexts](https://docs.cozy.io/en/cozy-stack/assets/#contexts) and [dynamic
   184      assets](https://docs.cozy.io/en/cozy-stack/cli/cozy-stack_config_insert-asset/)
   185      for more informations.
   186  -   `{{.Favicon}}` will be replaced by the favicon served by the stack.
   187  -   `{{.DefaultWallpaper}}` will be replaced by the URL to the default wallpaper.
   188  
   189  So, the `index.html` should probably looks like:
   190  
   191  ```html
   192  <!DOCTYPE html>
   193  <html lang="{{.Locale}}">
   194    <head>
   195      <meta charset="utf-8">
   196      <title>My Awesome App for Cozy</title>
   197      <meta name="viewport" content="width=device-width, initial-scale=1">
   198      <meta name="theme-color" content="#ffffff">
   199      <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials">
   200      <link rel="stylesheet" href="my-app.css">
   201      {{.ThemeCSS}}
   202      {{.CozyClientJS}}
   203      {{.CozyBar}}
   204    </head>
   205    <body>
   206      <div role="application" data-cozy="{{.CozyData}}"></div>
   207      <script src="my-app.js"></script>
   208    </body>
   209  </html>
   210  ```
   211  
   212  And `my-app.js`:
   213  
   214  ```js
   215  "use strict";
   216  
   217  document.addEventListener("DOMContentLoaded", () => {
   218    const app = document.querySelector("[role=application]");
   219    const data = app.dataset;
   220  
   221    cozy.client.init(data.cozy);
   222  
   223    cozy.bar.init({
   224      appEditor: data.cozy.app.editor,
   225      appName: data.cozy.app.name,
   226      iconPath: data.cozy.app.icon,
   227      lang: data.cozy.locale
   228    });
   229  
   230    // ...
   231  });
   232  ```