Tutorial: Developing a dashboard widget with Vue.js

I was following the Nextcloud tutorial “Developing a dashboard widget with Vue.js” to create a dashboard widget using Vue.

The dependencies I am using are:

{
  "@nextcloud/vue": "^9.8.2",
  "vue": "^3.5.35",
  "vue-material-design-icons": "^5.3.1"
}

When I ran:

npm run dev

the build failed with ESLint errors in the two source files:

  • src/dashboardVue.js

  • src/views/GifWidget.vue

The errors were:

Expected indentation of 1 tab but found 4 spaces
Expected indentation of 2 tabs but found 8 spaces
Expected indentation of 3 tabs but found 12 spaces

and:

Newline required at end of file but not found

Steps to reproduce

  1. Follow the Nextcloud tutorial “Developing a dashboard widget with Vue.js”.

  2. Use the dependencies:

{
  "@nextcloud/vue": "^9.8.2",
  "vue": "^3.5.35",
  "vue-material-design-icons": "^5.3.1"
}
  1. Copy the source code provided in the tutorial for:

    • dashboardVue.js

    • GifWidget.vue

  2. Run:

npm run dev
  1. The Vite build fails because ESLint expects tab indentation and a newline at the end of the files.

Error

For dashboardVue.js:

   5:1  error  Expected indentation of 1 tab but found 4 spaces    indent
   6:1  error  Expected indentation of 2 tabs but found 8 spaces   indent
   7:1  error  Expected indentation of 3 tabs but found 12 spaces  indent
   8:1  error  Expected indentation of 2 tabs but found 8 spaces   indent
   9:1  error  Expected indentation of 2 tabs but found 8 spaces   indent
  10:1  error  Expected indentation of 2 tabs but found 8 spaces   indent
  11:1  error  Expected indentation of 1 tab but found 4 spaces    indent
  12:3  error  Newline required at end of file but not found       eol-last

For GifWidget.vue:

82:9 error Newline required at end of file but not found  eol-last

Root cause

The source code provided in the tutorial does not appear to follow the current ESLint formatting rules used by the project.

In particular:

  • The indentation in dashboardVue.js uses spaces instead of tabs.

  • dashboardVue.js is missing the required newline at the end of the file.

  • GifWidget.vue is also missing the required newline at the end of the file.

You can verify the actual characters from WSL:

cat -A src/dashboardVue.js

You should see ^I for tabs:

^IOCA.Dashboard.register(...)
^I^Iconst app = createApp(...)
^I^I^Ititle: widget.title,

If you see like this, then they’re still spaces.:

    OCA.Dashboard
        const app

Solution

I manually changed the indentation in dashboardVue.js from spaces to tabs and added the missing newline at the end of the file.

I also added the missing newline at the end of GifWidget.vue.

After making these formatting changes, I ran:

npm run dev

and the project built successfully.

Suggestion

It would be helpful to update the source code in the tutorial so that the provided files conform to the ESLint configuration used by the current Nextcloud development environment.

Specifically, the code examples should:

  1. Use tabs for indentation where required by the ESLint configuration.

  2. Include a newline at the end of the source files.

This would prevent new users following the tutorial from encountering ESLint build errors immediately after copying the provided source code.

I did a quick check of the linked tutorials, checking the provided dasboardVue.js, and the tabs are there and retained when I cut-n-paste to a file.

Are you sure your editor didn’t strip formatting?

Yes, you were right, my editor was stripping/treating the indentation as spaces instead of actual tabs.

When I tried to debug it using:

cat -A src/dashboardVue.js

I found that the indentation was actually being treated as spaces, which helped me identify the issue and understand how to fix it.

Before - indentation was spaces

$ cat -A src/dashboardVue.js
import { createApp } from 'vue'$
$
import GifWidget from './views/GifWidget.vue'$
$
document.addEventListener('DOMContentLoaded', () => {$
    OCA.Dashboard.register('catgifsdashboard-vue-widget', (el, { widget }) => {$
        const app = createApp(GifWidget, {$
            title: widget.title,$
        })$
$
        app.mixin({ methods: { t, n } })$
        app.mount(el)$
    })$
})$

Here the indentation is spaces. cat -A does not show ^I at the beginning of the indented lines.

After - indentation was converted to actual tabs

$ cat -A src/dashboardVue.js
import { createApp } from 'vue'$
$
import GifWidget from './views/GifWidget.vue'$
$
document.addEventListener('DOMContentLoaded', () => {$
^IOCA.Dashboard.register('catgifsdashboard-vue-widget', (el, { widget }) => {$
^I^Iconst app = createApp(GifWidget, {$
^I^I^Ititle: widget.title,$
^I^I})$
$
^I^Iapp.mixin({ methods: { t, n } })$
^I^Iapp.mount(el)$
^I})$
})$

The important part is:

^I

That means actual Tab.

So, In VS Code, I opened the affected file and checked the bottom-right corner. It was showing:

Spaces: 4

I then selected:

Indent Using Tabs

and followed it with:

Convert Indentation to Tabs

The second option was important because it converted the existing spaces into actual tab characters.

After doing this, the ESLint indentation errors were resolved. So yes, in my case the editor was the issue rather than the tabs in the tutorial itself.

Ping @edward

You might be able to auto fix this as is is a trivial change which eslint might be able to auto fix.

When i was trying to run

npx eslint src/reference.js --no-ignore --fix

was getting this error

Oops! Something went wrong! 

ESLint: 8.57.1

ConfigError: Config (unnamed): Key "linterOptions": Unexpected key "reportUnusedInlineConfigs" found.
    at rethrowConfigError (/home/rsksofficial/nextcloud-docker-dev/workspace/server/apps-extra/pexels/node_modules/@humanwhocodes/config-array/api.js:230:8)
    at /home/rsksofficial/nextcloud-docker-dev/workspace/server/apps-extra/pexels/node_modules/@humanwhocodes/config-array/api.js:1032:5
    at Array.reduce (<anonymous>)
    at FlatConfigArray.getConfig (/home/rsksofficial/nextcloud-docker-dev/workspace/server/apps-extra/pexels/node_modules/@humanwhocodes/config-array/api.js:1028:39)
    at /home/rsksofficial/nextcloud-docker-dev/workspace/server/apps-extra/pexels/node_modules/eslint/lib/eslint/flat-eslint.js:812:40
    at Array.map (<anonymous>)
    at FlatESLint.lintFiles (/home/rsksofficial/nextcloud-docker-dev/workspace/server/apps-extra/pexels/node_modules/eslint/lib/eslint/flat-eslint.js:810:23)
    at async Object.execute (/home/rsksofficial/nextcloud-docker-dev/workspace/server/apps-extra/pexels/node_modules/eslint/lib/cli.js:421:23)
    at async main (/home/rsksofficial/nextcloud-docker-dev/workspace/server/apps-extra/pexels/node_modules/eslint/bin/eslint.js:152:22)

reportUnusedInlineConfigs is in ESLint >=9.x

Thanks @RSKSOFFICIAL , i was stuck in this for more than an hour.