{"id":13515677,"url":"https://github.com/nextcloud/text","last_synced_at":"2025-04-14T08:16:58.864Z","repository":{"id":37394354,"uuid":"176073581","full_name":"nextcloud/text","owner":"nextcloud","description":"📑 Collaborative document editing using Markdown","archived":false,"fork":false,"pushed_at":"2025-04-14T01:59:43.000Z","size":2227427,"stargazers_count":573,"open_issues_count":289,"forks_count":94,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-04-14T08:16:49.892Z","etag":null,"topics":["collaboration","collaborative","collaborative-editing","editor","hacktoberfest","javascript","js","markdown","nextcloud","nextcloud-app","nextcloud-text","prosemirror","rich-text","rich-text-editor","text","tiptap","vue","wysiwyg","wysiwyg-editor"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nextcloud.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-17T08:13:20.000Z","updated_at":"2025-04-14T01:58:48.000Z","dependencies_parsed_at":"2023-12-19T10:32:08.979Z","dependency_job_id":"75b0dcee-5e35-41c4-a835-fcc41e9ba9ae","html_url":"https://github.com/nextcloud/text","commit_stats":{"total_commits":5903,"total_committers":76,"mean_commits":77.67105263157895,"dds":0.791461968490598,"last_synced_commit":"3bc7f9d0900bed36427e3e1e41669feac6ab5c3a"},"previous_names":[],"tags_count":539,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextcloud%2Ftext","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextcloud%2Ftext/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextcloud%2Ftext/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextcloud%2Ftext/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nextcloud","download_url":"https://codeload.github.com/nextcloud/text/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248844000,"owners_count":21170499,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["collaboration","collaborative","collaborative-editing","editor","hacktoberfest","javascript","js","markdown","nextcloud","nextcloud-app","nextcloud-text","prosemirror","rich-text","rich-text-editor","text","tiptap","vue","wysiwyg","wysiwyg-editor"],"created_at":"2024-08-01T05:01:14.707Z","updated_at":"2025-04-14T08:16:58.833Z","avatar_url":"https://github.com/nextcloud.png","language":"JavaScript","readme":"\u003c!--\n  - SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors\n  - SPDX-License-Identifier: AGPL-3.0-or-later\n--\u003e\n# Nextcloud Text\n[![REUSE status](https://api.reuse.software/badge/github.com/nextcloud/text)](https://api.reuse.software/info/github.com/nextcloud/text)\n![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/nextcloud/text/node.yml?branch=main)\n[![Start contributing](https://img.shields.io/github/issues/nextcloud/text/good%20first%20issue?color=7057ff\u0026label=Contribute)](https://github.com/nextcloud/text/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22)\n\n\n**📑 Collaborative document editing!**\n\n![](img/screenshots/screenshot1.png)\n\n## Features\n\n- **📝 Simple focused writing:** No distractions, only the formatting you need.\n- **🙋 Work together:** Share and collaborate with friends and colleagues, no matter if they use Nextcloud or not!\n- **💾 Open format:** Files are saved as [Markdown](https://en.wikipedia.org/wiki/Markdown), so you can edit them from any other text app too.\n- **✊ Strong foundation:** We use [🐈 tiptap](https://tiptap.dev) which is based on [🦉 ProseMirror](https://prosemirror.net) – huge thanks to them!\n\nNextcloud Text is the default text editor since Nextcloud 17. To start editing just open an existing markdown or plaintext file or create a new one.\n\n## Configuration\n\nThe rich workspaces in the file list can be disabled either by the users in the files app settings or globally by the admin with the following occ command:\n\n```bash\nocc config:app:set text workspace_available --value=0\n```\n\nThe app can be configured to open files read-only by default. This setting is globally valid and can be set by the admin with the following command:\n\n```bash\nocc config:app:set text open_read_only_enabled --value=1\n```\n\n## 🏗 Development setup\n\nThis app requires the main branch of the [Viewer app](https://github.com/nextcloud/viewer) to be installed and enabled.\nFollow its development setup and then continue here.\n\n1. ☁ Clone this app into the `apps` folder of your Nextcloud: `git clone https://github.com/nextcloud/text.git`\n2. 👩‍💻 In the folder of the app, run the command `make` to install dependencies and build the Javascript.\n3. ✅ Enable the app through the app management of your Nextcloud\n4. 🎉 Partytime! Help fix [some issues](https://github.com/nextcloud/text/issues) and [review pull requests](https://github.com/nextcloud/text/pulls) 👍\n\n### Use hot module replacement via `vite serve`\n\nTo use the advantages of `vite serve` with hot module replacement (HMR) and not have to recompile the JS assets after each code change, do the following:\n\n1. Configure your webserver to redirect requests to `/apps/text/` to the vite serve server.\n   When using [nextcloud-docker-dev](https://github.com/juliusknorr/nextcloud-docker-dev), add the following snippet to `data/nginx/vhost.d/nextcloud.local` and restart the proxy container. You might have to replace `/apps/text/` with e.g. `/apps-extra/text/` depending on where the text app resides in your dev setup.\n   ```\n   location /apps/text/ {\n       proxy_pass http://host.docker.internal:5173/apps/text/;\n       # fallback to nextcloud server if vite serve doesn't answer\n       error_page 502 = @fallback;\n   }\n   location @fallback {\n       proxy_pass http://nextcloud.local;\n   }\n   ```\n2. Run `npm run serve` to start the vite serve server. If text resides somewhere else than `/apps/text`, run e.g. `BASE=/apps-extra/text npm run serve`.\n\nAfterwards all changes to the code will apply to the application in your browser automatically thanks to hot module replacement (HMR).\n   \n### 🧙 Advanced development stuff\n\nTo build the Javascript whenever you make changes, instead of the full `make` you can also run `npm run build`. Or run `npm run watch` to rebuild on every file save.\n\n#### 🐞 Testing the app\n\nCurrently, this app uses three different kinds of tests:\n\nFor testing the backend (PHP) [Psalm](https://psalm.dev/) and [PHPUnit](https://phpunit.de/) are used,\nyou can run the testcases (placed in `tests/`) using the composer scripts `psalm` and `test:unit`.\n\nFor testing the frontend [jest](https://jestjs.io/) is used for unittests, whereas [cypress](https://www.cypress.io/) is used for end2end testing.\nThe unittests are also placed in `src/tests/`, the cypress tests are placed in `cypress/`.\nYou can run the tests using the package scripts `npm run test` (jest), and respective `npm run test:cypress` (cypress).\n\nPlease note the cypress tests require a nextcloud server running, the if no running server is detected a docker container will be started,\nthis requires the current user to be in the `docker` group.\nOr you might set the `CYPRESS_baseUrl` environment variable for a custom nextcloud server.\n\n#### Adding support for other mime types\n\n- The mime type needs to be known by Nextcloud server (see https://github.com/nextcloud/server/pull/24488 for how this can be added)\n- Once that is there, please open a pull request to add them to https://github.com/nextcloud/text/blob/12df66ffdd3d71cc696438e2e4ec60fa17b89a64/src/helpers/mime.js#L35-L61\n- You can test them like other mime types in cypress/e2e/files.spec.js\n\n\n## 🛠️ Integrate text in your app\n\n## Load the editor\n\nIn order to load the editor in your app, you'll need to dispatch an event.\n\n```php\nuse OCA\\Text\\Event\\LoadEditor;\n\n// ...\n\nif (class_exists(LoadEditor::class)) {\n\t$this-\u003eeventDispatcher-\u003edispatchTyped(new LoadEditor());\n}\n```\n\n### Integrate a file editor\n\nMake sure to check if OCA.Text is available as the Text app needs to be enabled. If you want your app to work without Text being installed, you will need to provide an editor fallback on your own.\n\n\n```js\nwindow.OCA.Text.createEditor({\n\tel: document.getElementById('my-editor-div'),\n\tfileId: 12345,\n\tfilePath: '/Readme.md',\n}).then((editor) =\u003e {\n\t// Once ready you can access the editor instance and call methods like:\n\n\teditor.setContent('new content') // Beware: this will overwrite the content read from the source file\n\teditor.setReadOnly(true)\n\teditor.insertAtCursor('\u003ch1\u003eHeading\u003c/h1\u003e')\n\n\t// Make sure to destory the editor instance once you remove the dom element\n\teditor.destroy()\n})\n```\n\n### Markdown based content editor\n\n```js\nwindow.OCA.Text.createEditor({\n\tel: document.getElementById('my-editor-div'),\n\tcontent: 'initial content',\n}).then((editor) =\u003e {\n\t// Once ready you can access the editor instance and call methods like:\n\n\teditor.setContent('new content')\n\teditor.setReadOnly(true)\n\teditor.insertAtCursor('\u003ch1\u003eHeading\u003c/h1\u003e')\n\n\t// Make sure to destory the editor instance once you remove the dom element\n\teditor.destroy()\n})\n```\n","funding_links":[],"categories":["JavaScript","markdown","Open source projects using Tiptap"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnextcloud%2Ftext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnextcloud%2Ftext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnextcloud%2Ftext/lists"}