Add documentation website (#833)

* test frontmatter rendering

* restructure files

* add docs website

* move postcss config

* revert postcss config

* update readme

* update logo

* fix internal links
This commit is contained in:
Sascha Ißbrücker
2024-09-17 15:33:53 +02:00
committed by GitHub
parent 53e4aeb1c1
commit 0e488b7ce3
37 changed files with 8153 additions and 248 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 KiB

View File

@@ -0,0 +1,95 @@
{
"categories": [
{
"id": "e260b423-db01-4743-a671-2cd38594c63c",
"layoutType": "wide_grid",
"name": "Shortcuts",
"shortcuts": [
{
"bodyContent": "{{7b26d228-4ad6-4b1c-8b7b-076dc03385cc}}",
"codeOnPrepare": "const sharedValue \u003d getVariable(\u0027text_and_url\u0027)\nconst matches \u003d sharedValue.match(/\\bhttps?:\\/\\/\\S+/gi);\nconst url \u003d matches[0];\nsetVariable(\u0027cleaned_url\u0027, url);",
"contentType": "application/json",
"description": "bookmark link",
"headers": [
{
"id": "b66dd9b9-13e8-4802-b527-6e32f3980f4b",
"key": "Authorization",
"value": "Token {{908e3a30-ae82-400d-93c8-561c36d11d6d}}"
}
],
"iconName": "flat_grey_pin",
"id": "871c3219-9e9f-46bb-8a7f-78f1496f78fc",
"method": "POST",
"name": "Linkding",
"responseHandling": {
"failureOutput": "simple",
"uiType": "toast"
},
"url": "{{26253fe2-d202-4ce8-acd1-55c1ad3ae7d1}}/api/bookmarks/"
}
]
}
],
"variables": [
{
"id": "26253fe2-d202-4ce8-acd1-55c1ad3ae7d1",
"key": "linkding_instance",
"value": "https://your.linkding.host.no.slashed.end"
},
{
"id": "a3c8efa2-3e3a-4bb4-8919-3e831f95fe6a",
"jsonEncode": true,
"key": "linkding_tag",
"message": "Comma separated",
"title": "One or more tags",
"type": "text"
},
{
"id": "908e3a30-ae82-400d-93c8-561c36d11d6d",
"key": "linkding_api_key",
"value": "your_api_key_here"
},
{
"id": "d76696e7-1ee1-4d98-b6f9-b570ec69ef40",
"key": "cleaned_url"
},
{
"flags": 1,
"id": "da66cdad-8118-4a87-9581-4db33852b610",
"key": "text_and_url",
"message": "Any text that contains one URL",
"title": "URL",
"type": "text"
},
{
"data": "{\"select\":{\"multi_select\":\"false\",\"separator\":\",\"}}",
"id": "7b26d228-4ad6-4b1c-8b7b-076dc03385cc",
"key": "tag_yes_no_default",
"options": [
{
"id": "9365e43e-0572-4621-ac06-caec1ccff09d",
"label": "Tagged",
"value": "{{5be61e61-d8f5-475b-b1b1-88ddaebf8fd5}}"
},
{
"id": "9f1caeaf-af57-42b4-8b10-4391354ad0f0",
"label": "Untagged and unread",
"value": "{{71ac9c4d-c03e-4b6f-ad75-9c112a591c50}}"
}
],
"title": "Tagged or unread?",
"type": "select"
},
{
"id": "5be61e61-d8f5-475b-b1b1-88ddaebf8fd5",
"key": "request_body_tagged",
"value": "{ \"url\": \"{{d76696e7-1ee1-4d98-b6f9-b570ec69ef40}}\", \"tag_names\": [ \"{{a3c8efa2-3e3a-4bb4-8919-3e831f95fe6a}}\" ] }"
},
{
"id": "71ac9c4d-c03e-4b6f-ad75-9c112a591c50",
"key": "request_body_untagged",
"value": "{ \"url\": \"{{d76696e7-1ee1-4d98-b6f9-b570ec69ef40}}\", \"unread\": true }"
}
],
"version": 56
}

17
docs/src/assets/logo.svg Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 450 450" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.5;">
<g transform="matrix(1,0,0,1,-70.3466,-70.3466)">
<g transform="matrix(1.18075,0,0,1.18075,-1257.39,-1386.74)">
<circle cx="1314.98" cy="1424.52" r="190.496" style="fill:rgb(88,86,224);"/>
</g>
<g transform="matrix(0.793058,0,0,0.793058,-739.034,-836.215)">
<g transform="matrix(0.707351,0.706862,-0.706862,0.707351,1331.93,-512.804)">
<path d="M1244.39,1293.95L1244.39,1493.59C1244.39,1493.59 1243.58,1561.48 1319.29,1562.47C1395.27,1563.46 1394.17,1493.59 1394.17,1493.59L1394.17,1293.95" style="fill:none;stroke:white;stroke-width:34.15px;"/>
</g>
<g transform="matrix(-0.710067,-0.704134,0.704134,-0.710067,1284.12,3366.41)">
<path d="M1244.39,1293.95L1244.39,1493.59C1244.39,1493.59 1243.58,1561.48 1319.29,1562.47C1395.27,1563.46 1394.17,1493.59 1394.17,1493.59L1394.17,1293.95" style="fill:none;stroke:white;stroke-width:34.15px;"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,6 @@
import { defineCollection } from 'astro:content';
import { docsSchema } from '@astrojs/starlight/schema';
export const collections = {
docs: defineCollection({ schema: docsSchema() }),
};

View File

@@ -0,0 +1,18 @@
---
title: "Acknowledgements"
description: "Acknowledgements and thanks to contributors and sponsors"
---
## PikaPods
[PikaPods](https://www.pikapods.com/) has a revenue sharing agreement with this project, sharing some of their revenue from hosting linkding instances. I do not intend to profit from this project financially, so I am in turn donating that revenue. Thanks to PikaPods for making this possible.
See the table below for a list of donations.
| Source | Description | Amount | Donated to |
|---------------------------------------|---------------------------------------------|---------|------------------------------------------------------------------|
| [PikaPods](https://www.pikapods.com/) | Linkding hosting June 2022 - September 2023 | $163.50 | [Internet Archive](/2023-10-11-internet-archive.png) |
## JetBrains
JetBrains has previously provided an open-source license of [IntelliJ IDEA](https://www.jetbrains.com/idea/) for the development of linkding. Thanks!

View File

@@ -0,0 +1,68 @@
---
title: "Admin"
description: "How to use the linkding admin app"
---
This document describes how to make use of the admin app that comes as part of each linkding installation. This is the default Django admin app with some linkding specific customizations.
The admin app provides several features that are not available in the linkding UI:
- User management and user self-management
- Bookmark and tag management, including bulk operations
## Linkding administration page
To open the Admin app, go the *Settings* view and click on the *Admin* tab. This should open a new window with the admin app.
Alternatively you can open the URL directly by adding `/admin` to the URL of your linkding installation.
## User management
Go to the linkding administration page and select *Users*.
Here you can add and delete users, and change the password of a user.
Once you have added a user you can, if needed, give the user staff status, which means this user can also access the linkding administration page.
This page also allows you to change your own password if necessary.
## Bookmark management
While the linkding UI itself now has a bulk edit feature for bookmarks you can also use the admin app to manage bookmarks or to do bulk operations.
In the main linkding administration page, choose *Bookmarks*.
First select the bookmarks to operate on:
- Specify a filter to determine which bookmarks to operate on:
- In the column *by username*, you can choose to filter for bookmarks for a specific user
- In the column *by is archived*, you can choose to filter for bookmarks that are either archived or not
- In the column *by tags*, you can choose to filter for specific tags
- In the search box you can also add a text filter (note that this doesn't use the same search syntax as the linkding UI itself)
Now a list of bookmarks which match your filter is displayed, each bookmark on a separate line.
Each line starts with a checkbox.
Either choose the individual bookmarks you want to do a bulk operation on, or choose the top checkbox to select all shown bookmarks.
Open the "Action" select box to choose the desired bulk operation:
- Delete
- Archive
- Unarchive
Click the button next to the checkbox to execute the operation.
## Tag management
While linkding UI currently only allows to create or assign tags, you can use the admin app to manage your tags. This can be especially useful if you want to clean up your tag collection.
In the main linkding administration page, choose *Tags*.
Similar to bookmarks management described above you can now specify which tags to operate on by specifying a filter and then selecting the individual tags.
Open the "Action" select box to choose the desired bulk operation:
- Delete
- Delete unused tags - this will only delete the selected tags that are currently not assigned to any bookmark
Click the button next to the checkbox to execute the operation.
Note that deleting a tag does not affect the bookmarks that are tagged with this tag, it only removes the tag from those bookmarks.

View File

@@ -0,0 +1,276 @@
---
title: "API"
description: "How to use the REST API of linkding"
---
The application provides a REST API that can be used by 3rd party applications to manage bookmarks.
## Authentication
All requests against the API must be authorized using an authorization token. The application automatically generates an API token for each user, which can be accessed through the *Settings* page.
The token needs to be passed as `Authorization` header in the HTTP request:
```
Authorization: Token <Token>
```
## Resources
The following resources are available:
### Bookmarks
**List**
```
GET /api/bookmarks/
```
List bookmarks.
Parameters:
- `q` - Filters results using a search phrase using the same logic as through the UI
- `limit` - Limits the max. number of results. Default is `100`.
- `offset` - Index from which to start returning results
Example response:
```json
{
"count": 123,
"next": "http://127.0.0.1:8000/api/bookmarks/?limit=100&offset=100",
"previous": null,
"results": [
{
"id": 1,
"url": "https://example.com",
"title": "Example title",
"description": "Example description",
"notes": "Example notes",
"website_title": "Website title",
"website_description": "Website description",
"web_archive_snapshot_url": "https://web.archive.org/web/20200926094623/https://example.com",
"favicon_url": "http://127.0.0.1:8000/static/https_example_com.png",
"preview_image_url": "http://127.0.0.1:8000/static/0ac5c53db923727765216a3a58e70522.jpg",
"is_archived": false,
"unread": false,
"shared": false,
"tag_names": [
"tag1",
"tag2"
],
"date_added": "2020-09-26T09:46:23.006313Z",
"date_modified": "2020-09-26T16:01:14.275335Z"
},
...
]
}
```
**List Archived**
```
GET /api/bookmarks/archived/
```
List archived bookmarks.
Parameters and response are the same as for the regular list endpoint.
**Retrieve**
```
GET /api/bookmarks/<id>/
```
Retrieves a single bookmark by ID.
**Create**
```
POST /api/bookmarks/
```
Creates a new bookmark. Tags are simply assigned using their names. Including
`is_archived: true` saves a bookmark directly to the archive.
Example payload:
```json
{
"url": "https://example.com",
"title": "Example title",
"description": "Example description",
"notes": "Example notes",
"is_archived": false,
"unread": false,
"shared": false,
"tag_names": [
"tag1",
"tag2"
]
}
```
**Update**
```
PUT /api/bookmarks/<id>/
```
Updates a bookmark.
This is a full update, which requires at least a URL, and fields that are not specified are cleared or reset to their defaults.
Tags are simply assigned using their names.
Example payload:
```json
{
"url": "https://example.com",
"title": "Example title",
"description": "Example description",
"tag_names": [
"tag1",
"tag2"
]
}
```
**Patch**
```
PATCH /api/bookmarks/<id>/
```
Updates a bookmark partially.
Allows to modify individual fields of a bookmark.
Tags are simply assigned using their names.
Example payload:
```json
{
"url": "https://example.com",
"title": "Example title",
"description": "Example description",
"tag_names": [
"tag1",
"tag2"
]
}
```
**Archive**
```
POST /api/bookmarks/<id>/archive/
```
Archives a bookmark.
**Unarchive**
```
POST /api/bookmarks/<id>/unarchive/
```
Unarchives a bookmark.
**Delete**
```
DELETE /api/bookmarks/<id>/
```
Deletes a bookmark by ID.
### Tags
**List**
```
GET /api/tags/
```
List tags.
Parameters:
- `limit` - Limits the max. number of results. Default is `100`.
- `offset` - Index from which to start returning results
Example response:
```json
{
"count": 123,
"next": "http://127.0.0.1:8000/api/tags/?limit=100&offset=100",
"previous": null,
"results": [
{
"id": 1,
"name": "example",
"date_added": "2020-09-26T09:46:23.006313Z"
},
...
]
}
```
**Retrieve**
```
GET /api/tags/<id>/
```
Retrieves a single tag by ID.
**Create**
```
POST /api/tags/
```
Creates a new tag.
Example payload:
```json
{
"name": "example"
}
```
### User
**Profile**
```
GET /api/user/profile/
```
User preferences.
Example response:
```json
{
"theme": "auto",
"bookmark_date_display": "relative",
"bookmark_link_target": "_blank",
"web_archive_integration": "enabled",
"tag_search": "lax",
"enable_sharing": true,
"enable_public_sharing": true,
"enable_favicons": false,
"display_url": false,
"permanent_notes": false,
"search_preferences": {
"sort": "title_asc",
"shared": "off",
"unread": "off"
}
}
```

View File

@@ -0,0 +1,130 @@
---
title: "Backups"
description: "How to back up your Linkding installation"
---
Linkding stores all data in the application's data folder.
The full path to that folder in the Docker container is `/etc/linkding/data`.
As described in the installation docs, you should mount the `/etc/linkding/data` folder to a folder on your host system.
The data folder contains the following contents that are relevant for backups:
- `db.sqlite3` - the SQLite database
- `assets` - folder that contains HTML snapshots of bookmarks
- `favicons` - folder that contains downloaded favicons
- `previews` - folder that contains downloaded preview images
The following sections explain how to back up the individual contents.
## Full backup
linkding provides a CLI command to create a full backup of the data folder. This creates a zip file that contains backups of the database, assets, favicons, and preview images.
:::note
This method assumes that you are using the default SQLite database.
If you are using a different database, such as Postgres, you'll have to back up the database and other contents of the data folder manually.
:::
To create a full backup, execute the following command:
```shell
docker exec -it linkding python manage.py full_backup /etc/linkding/data/backup.zip
```
This creates a `backup.zip` file in the Docker container under `/etc/linkding/data`.
To copy the backup file to your host system, execute the following command:
```shell
docker cp linkding:/etc/linkding/data/backup.zip backup.zip
```
This copies the backup file from the Docker container to the current folder on your host system.
Now you can move that file to your backup location.
To restore a backup:
- Extract the zip file in a folder of your new installation.
- Rename the extracted folder to `data`.
- When starting the Docker container, mount that folder to `/etc/linkding/data` as explained in the README.
- Then start the Docker container.
## Alternative backup methods
If you can't use the full backup method, this section describes alternatives how to back up the individual contents of the data folder.
### SQLite database backup
linkding includes a CLI command for creating a backup copy of the database.
:::caution
While the SQLite database is just a single file, it is not recommended to just copy that file.
This method is not transaction safe and may result in a [corrupted database](https://www.sqlite.org/howtocorrupt.html).
Use one of the backup methods described below.
:::
:::caution
This method is deprecated and may be removed in the future.
Please use the full backup method described above.
:::
To create a backup, execute the following command:
```shell
docker exec -it linkding python manage.py backup /etc/linkding/data/backup.sqlite3
```
This creates a `backup.sqlite3` file in the Docker container under `/etc/linkding/data`.
To copy the backup file to your host system, execute the following command:
```shell
docker cp linkding:/etc/linkding/data/backup.sqlite3 backup.sqlite3
```
This copies the backup file from the Docker container to the current folder on your host system.
Now you can move that file to your backup location.
To restore the backup, just copy the backup file to the data folder of your new installation and rename it to `db.sqlite3`. Then start the Docker container.
### SQLite database SQL dump
Requires [SQLite](https://www.sqlite.org/index.html) to be installed on your host system.
With this method you create a plain text file with the SQL statements to recreate the SQLite database.
To create a backup, execute the following command in the data folder on your host system:
```shell
sqlite3 db.sqlite3 .dump > backup.sql
```
This creates a `backup.sql` which you can copy to your backup location.
As this is a plain text file you can also commit it to any revision management system, like git.
Using git, you can commit the changes, followed by a git push to a remote repository.
### Exporting bookmarks from the UI
This is the least technical option to back up bookmarks, but has several limitations:
- It does not export user profiles.
- It only exports your own bookmarks, not those of other users.
- It does not export URLs of snapshots on the Internet Archive Wayback machine.
- It does not export HTML snapshots of bookmarks. Even if you backup and restore the assets folder, the bookmarks will not be linked to the snapshots anymore.
- It does not export favicons or preview images.
Only use this method if you are fine with the above limitations.
To export bookmarks from the UI, open the general settings.
In the Export section, click on the *Download* button to download an HTML file containing all your bookmarks.
Then move that file to your backup location.
To restore bookmarks, open the general settings on your new installation.
In the Import section, click on the *Choose file* button to select the HTML file you downloaded before.
Then click on the *Import* button to import the bookmarks.
### Assets
If you are using the HTML snapshots feature, you should also do backups of the `assets` folder.
It contains the HTML snapshots files of your bookmarks which are referenced from the database.
To back up the assets, then you have to copy the `assets` folder to your backup location.
To restore the assets, copy the `assets` folder back to the data folder of your new installation.
### Favicons
Doing a backup of the icons is optional, as they can be downloaded again.
If you choose not to back up the icons, you can just restore the database and then click the _Refresh Favicons_ button in the general settings.
This will download all missing icons again.
If you want to back up the icons, then you have to copy the `favicons` folder to your backup location.
To restore the icons, copy the `favicons` folder back to the data folder of your new installation.

View File

@@ -0,0 +1,10 @@
---
title: "Browser Extension"
description: "Browser extension for linkding"
---
linkding comes with an official browser extension that allows to quickly add bookmarks, and search bookmarks through the browser's address bar. You can get the extension here:
- [Mozilla Addon Store](https://addons.mozilla.org/firefox/addon/linkding-extension/)
- [Chrome Web Store](https://chrome.google.com/webstore/detail/linkding-extension/beakmhbijpdhipnjhnclmhgjlddhidpe)
The extension is open-source as well, and can be found [here](https://github.com/sissbruecker/linkding-extension).

View File

@@ -0,0 +1,21 @@
---
title: "Community"
description: "Community projects around linkding"
---
This section lists community projects around using linkding, in alphabetical order. If you have a project that you want to share with the linkding community, feel free to [submit a PR](https://github.com/sissbruecker/linkding/edit/master/docs/community.md) to add your project to this section.
- [aiolinkding](https://github.com/bachya/aiolinkding) A Python3, async library to interact with the linkding REST API. By [bachya](https://github.com/bachya)
- [feed2linkding](https://codeberg.org/strubbl/feed2linkding) A commandline utility to add all web feed item links to linkding via API call. By [Strubbl](https://github.com/Strubbl)
- [Helm Chart](https://charts.pascaliske.dev/charts/linkding/) Helm Chart for deploying linkding inside a Kubernetes cluster. By [pascaliske](https://github.com/pascaliske)
- [iOS Shortcut using API and Tagging](https://gist.github.com/andrewdolphin/a7dff49505e588d940bec55132fab8ad) An iOS shortcut using the Linkding API (no extra logins required) that pulls previously used tags and allows tagging at the time of link creation.
- [k8s + s3](https://github.com/jzck/linkding-k8s-s3) - Setup for hosting stateless linkding on k8s with sqlite replicated to s3. By [jzck](https://github.com/jzck)
- [Linka!](https://github.com/cmsax/linka) Web app (also a PWA) for quickly searching & opening bookmarks in linkding, support multi keywords, exclude mode and other advance options. By [cmsax](https://github.com/cmsax)
- [linkding-cli](https://github.com/bachya/linkding-cli) A command-line interface (CLI) to interact with the linkding REST API. Powered by [aiolinkding](https://github.com/bachya/aiolinkding). By [bachya](https://github.com/bachya)
- [linkding-extension](https://github.com/jeroenpardon/linkding-extension) Chromium compatible extension that wraps the linkding bookmarklet. Tested with Chrome, Edge, Brave. By [jeroenpardon](https://github.com/jeroenpardon)
- [linkding-injector](https://github.com/Fivefold/linkding-injector) Injects search results from linkding into the sidebar of search pages like google and duckduckgo. Tested with Firefox and Chrome. By [Fivefold](https://github.com/Fivefold)
- [Linkdy](https://github.com/JGeek00/linkdy): An open source mobile and desktop (not yet) client created with Flutter. Available at the [Google Play Store](https://play.google.com/store/apps/details?id=com.jgeek00.linkdy). By [JGeek00](https://github.com/JGeek00).
- [LinkThing](https://apps.apple.com/us/app/linkthing/id1666031776) An iOS client for linkding. By [amoscardino](https://github.com/amoscardino)
- [Open all links bookmarklet](https://gist.github.com/ukcuddlyguy/336dd7339e6d35fc64a75ccfc9323c66) A browser bookmarklet to open all links on the current Linkding page in new tabs. By [ukcuddlyguy](https://github.com/ukcuddlyguy)
- [Pinkt](https://github.com/fibelatti/pinboard-kotlin) An Android client for linkding. By [fibelatti](https://github.com/fibelatti)
- [Postman collection](https://gist.github.com/gingerbeardman/f0b42502f3bc9344e92ce63afd4360d3) a group of saved request templates for API testing. By [gingerbeardman](https://github.com/gingerbeardman)

View File

@@ -0,0 +1,89 @@
---
title: "How to"
description: "Collection of tips and tricks around using linkding"
---
Collection of tips and tricks around using linkding.
## Using the bookmarklet on Android/Chrome
This how-to explains the usage of the standard linkding bookmarklet on Android / Chrome.
Chrome on Android does not permit running bookmarklets in the same way you can on a desktop system. There is however a workaround that is explained here.
**Note** that this only works with Chrome and not with other browsers on Android.
Create a bookmark of your linkding deployment by clicking the star icon which you find in the three dots menu in the top right. Next you have to edit the bookmark. Edit the URL and replace it it with the bookmarklet code of your instance and give it an easy to type name like `bm` for bookmark or `ld` for linkding:
```
javascript:window.open(`http://<YOUR_INSTANCE_HERE>/bookmarks/new?url=${encodeURIComponent(window.location)}&auto_close`)
```
Now when you are browsing the web and you want to save the current page as a bookmark to your linkding instance simply type `bm` into the address bar and select it from the results. The bookmarklet code will trigger and you will be redirected so save the current page.
For more info see here: https://paul.kinlan.me/use-bookmarklets-on-chrome-on-android/
## Using HTTP Shortcuts app on Android
**Note** This allows you to share URL from any app to tag and bookmark it to linkding
- Install HTTP Shortcuts from [Play Store](https://play.google.com/store/apps/details?id=ch.rmy.android.http_shortcuts) or [F-Droid](https://f-droid.org/en/packages/ch.rmy.android.http_shortcuts/).
- Copy the URL of [linkding_shortcut.json](https://raw.githubusercontent.com/sissbruecker/linkding/master/docs/src/assets/linkding_shortcut.json).
- Open HTTP Shortcuts, tap the 3-dot-button at the top-right corner, tap `Import/Export`, then tap `Import from URL`.
- Paste the URL you copied earlier, tap OK, go back, tap the 3-dot-button again, then tap `Variables`.
- Edit the `values` of `linkding_instance` and `linkding_api_key`.
Try using share button on an app, a new item `Send to...` should appear on the share sheet. You can also manually share by tapping the shortcut inside the HTTP Shortcuts app itself.
## Create a share action on iOS for adding bookmarks to linkding
This how-to explains how to make use of the app shortcuts iOS app to create a share action that can be used in Safari for adding bookmarks to your linkding instance.
To install the shortcut:
- Download the [Shortcut](https://raw.githubusercontent.com/sissbruecker/linkding/master/docs/src/assets/Add%20To%20Linkding.shortcut) on your iOS device
- Tap the downloaded file, which brings up the Shortcuts app
- Confirm that you want to add the shortcut
- In the shortcut, change `https://linkding.mydomain.com` to the URL of your linkding instance
- Confirm / close the shortcut
To use the shortcut:
- Open Safari and navigate to the page you want to bookmark
- Tap the share button
- Scroll down and tap "Add To Linkding"
- This opens linkding in a Safari overlay where you can configure the bookmark
- When you're done, tap "Save"
- After the bookmark is saved you can close the overlay
At the bottom of the share sheet there is a button for configuring share actions. You can use this to move the "Add To Linkding" action to the top of the share sheet if you like.
:::note
You can also check the [Community section](/community) for other pre-made shortcuts that you can use.
:::
## Increase the font size
The font size can be adjusted globally by adding the following CSS to the custom CSS field in the settings:
```css
html {
--font-size: 0.75rem;
--font-size-sm: 0.7rem;
--font-size-lg: 0.9rem;
}
.bookmark-list {
line-height: 1.15rem;
}
.tag-cloud {
line-height: 1.15rem;
}
```
You can adjust the `--font-size`, `--font-size-sm` and `--font-size-lg` variables to your liking.
Note that increasing the font might also require you to adjust the line-height in certain places to better separate texts from each other.
As an example, the above also increases the font size and line height of the bookmark list and tag cloud.

View File

@@ -0,0 +1,33 @@
---
title: "Linkding"
description: "Linkding is a self-hosted bookmarking service that is designed be to be minimal, fast, and easy to set up using Docker."
---
linkding is a bookmark manager that you can host yourself.
It's designed be to be minimal, fast, and easy to set up using Docker.
The name comes from:
- *link* which is often used as a synonym for URLs and bookmarks in common language
- *Ding* which is German for thing
- ...so basically something for managing your links
**Feature Overview:**
- Clean UI optimized for readability
- Organize bookmarks with tags
- Bulk editing, Markdown notes, read it later functionality
- Share bookmarks with other users or guests
- Automatically provides titles, descriptions and icons of bookmarked websites
- Automatically archive websites, either as local HTML file or on Internet Archive
- Import and export bookmarks in Netscape HTML format
- Installable as a Progressive Web App (PWA)
- Extensions for [Firefox](https://addons.mozilla.org/firefox/addon/linkding-extension/) and [Chrome](https://chrome.google.com/webstore/detail/linkding-extension/beakmhbijpdhipnjhnclmhgjlddhidpe), as well as a bookmarklet
- SSO support via OIDC or authentication proxies
- REST API for developing 3rd party apps
- Admin panel for user self-service and raw data access
**Demo:** https://demo.linkding.link/
**Screenshot:**
![Screenshot](../../assets/linkding-screenshot.png)

View File

@@ -0,0 +1,143 @@
---
title: "Installation"
description: "How to install linkding"
---
linkding is designed to be run with container solutions like [Docker](https://docs.docker.com/get-started/).
The Docker image is compatible with ARM platforms, so it can be run on a Raspberry Pi.
linkding uses an SQLite database by default.
Alternatively, linkding supports PostgreSQL, see the [database options](/options#ld_db_engine) for more information.
## Using Docker
The Docker image comes in several variants. To use a different image than the default, replace `latest` with the desired tag in the commands below, or in the docker-compose file.
<table>
<thead>
<tr>
<th>Tag</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>latest</code></td>
<td>Provides the basic functionality of linkding</td>
</tr>
<tr>
<td><code>latest-plus</code></td>
<td>
Includes feature for archiving websites as HTML snapshots
<ul>
<li>Significantly larger image size as it includes a Chromium installation</li>
<li>Requires more runtime memory to run Chromium</li>
<li>Requires more disk space for storing HTML snapshots</li>
</ul>
</td>
</tr>
<tr>
<td><code>latest-alpine</code></td>
<td><code>latest</code>, but based on Alpine Linux. 🧪 Experimental</td>
</tr>
<tr>
<td><code>latest-plus-alpine</code></td>
<td><code>latest-plus</code>, but based on Alpine Linux. 🧪 Experimental</td>
</tr>
</tbody>
</table>
To install linkding using Docker you can just run the image from [Docker Hub](https://hub.docker.com/repository/docker/sissbruecker/linkding):
```shell
docker run --name linkding -p 9090:9090 -v {host-data-folder}:/etc/linkding/data -d sissbruecker/linkding:latest
```
In the command above, replace the `{host-data-folder}` placeholder with an absolute path to a folder on your host system where you want to store the linkding database.
If everything completed successfully, the application should now be running and can be accessed at http://localhost:9090.
To upgrade the installation to a new version, remove the existing container, pull the latest version of the linkding Docker image, and then start a new container using the same command that you used above. There is a [shell script](https://github.com/sissbruecker/linkding/blob/master/install-linkding.sh) available to automate these steps. The script can be configured using environment variables, or you can just modify it.
To complete the setup, you still have to [create an initial user](#user-setup), so that you can access your installation.
## Using Docker Compose
To install linkding using [Docker Compose](https://docs.docker.com/compose/), you can download the [`docker-compose.yml`](https://github.com/sissbruecker/linkding/blob/master/docker-compose.yml) file. Also download the [`.env.sample`](https://github.com/sissbruecker/linkding/blob/master/.env.sample) file, rename it to `.env`, configure the parameters, and then run:
```shell
docker-compose up -d
```
To complete the setup, you still have to [create an initial user](#user-setup), so that you can access your installation.
## User Setup
The linkding Docker image does not provide an initial user, so you have to create one after setting up an installation. To do so, replace the credentials in the following command and run it:
**Docker**
```shell
docker exec -it linkding python manage.py createsuperuser --username=joe --email=joe@example.com
```
**Docker Compose**
```shell
docker-compose exec linkding python manage.py createsuperuser --username=joe --email=joe@example.com
```
The command will prompt you for a secure password. After the command has completed you can start using the application by logging into the UI with your credentials.
Alternatively, you can automatically create an initial superuser on startup using the [`LD_SUPERUSER_NAME` option](/options#ld_superuser_name).
## Reverse Proxy Setup
When using a reverse proxy, such as Nginx or Apache, you may need to configure your proxy to correctly forward the `Host` header to linkding, otherwise certain requests, such as login, might fail.
<details>
<summary>Apache</summary>
Apache2 does not change the headers by default, and should not
need additional configuration.
An example virtual host that proxies to linkding might look like:
```
<VirtualHost *:9100>
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://linkding:9090/
ProxyPassReverse / http://linkding:9090/
</VirtualHost>
```
For a full example, see the docker-compose configuration in [jhauris/apache2-reverse-proxy](https://github.com/jhauris/linkding/tree/apache2-reverse-proxy)
If you still run into CSRF issues, please check out the [`LD_CSRF_TRUSTED_ORIGINS` option](/options#ld_csrf_trusted_origins).
</details>
<details>
<summary>Caddy 2</summary>
Caddy does not change the headers by default, and should not need any further configuration.
If you still run into CSRF issues, please check out the [`LD_CSRF_TRUSTED_ORIGINS` option](/options#ld_csrf_trusted_origins).
</details>
<details>
<summary>Nginx</summary>
Nginx by default rewrites the `Host` header to whatever URL is used in the `proxy_pass` directive.
To forward the correct headers to linkding, add the following directives to the location block of your Nginx config:
```
location /linkding {
...
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
```
</details>
Instead of configuring header forwarding in your proxy, you can also configure the URL from which you want to access your linkding instance with the [`LD_CSRF_TRUSTED_ORIGINS` option](/options#ld_csrf_trusted_origins).

View File

@@ -0,0 +1,20 @@
---
title: "Managed Hosting"
description: "Managed hosting options for linkding"
---
Self-hosting web applications still requires a lot of technical know-how and commitment to maintenance, in order to keep everything up-to-date and secure. This section is intended to provide simple alternatives in form of managed hosting solutions.
## Fully Managed
The following services provide fully managed hosting for linkding, including automatic updates and backups:
- [PikaPods.com](https://www.pikapods.com/) - Managed hosting for linkding, EU and US regions available. [1-click setup link](https://www.pikapods.com/pods?run=linkding) ([Disclosure](/acknowledgements#pikapods))
## Self-Managed
The following guides provide instructions for hosting a linkding installation on various platforms, however you are still responsible for updates and backups:
- [linkding on fly.io](https://github.com/fspoettel/linkding-on-fly) - Guide for hosting a linkding installation on [fly.io](https://fly.io). By [fspoettel](https://github.com/fspoettel)
- [CapRover](https://caprover.com/) - Linkding is included as a default one-click app
- [linkding on railway.app](https://github.com/tianheg/linkding-on-railway) - Guide for hosting a linkding installation on [railway.app](https://railway.app/). By [tianheg](https://github.com/tianheg)

View File

@@ -0,0 +1,270 @@
---
title: "Options"
description: "Options for configuring linkding"
---
This document lists the options that linkding can be configured with and explains how to use them in the individual install scenarios.
## Using options
### Docker
Options are passed as environment variables to the Docker container by using the `-e` argument when using `docker run`. For example:
```
docker run --name linkding -p 9090:9090 -d -e LD_DISABLE_URL_VALIDATION=True sissbruecker/linkding:latest
```
For multiple options, use one `-e` argument per option.
### Docker-compose
For docker-compose options are configured using an `.env` file.
Follow the docker-compose setup in the README and copy `.env.sample` to `.env`. Then modify the options in `.env`.
## List of options
### `LD_SUPERUSER_NAME`
Values: `String` | Default = None
When set, creates an initial superuser with the specified username when starting the container.
Does nothing if the user already exists.
See [`LD_SUPERUSER_PASSWORD`](#ld_superuser_password) on how to configure the respective password.
### `LD_SUPERUSER_PASSWORD`
Values: `String` | Default = None
The password for the initial superuser.
When left undefined, the superuser will be created without a usable password, which means the user can not authenticate using credentials / through the login form, and can only be authenticated using proxy authentication (see [`LD_ENABLE_AUTH_PROXY`](#ld_enable_auth_proxy)).
### `LD_DISABLE_BACKGROUND_TASKS`
Values: `True`, `False` | Default = `False`
Disables background tasks, such as creating snapshots for bookmarks on the [the Internet Archive Wayback Machine](https://archive.org/web/).
Enabling this flag will prevent the background task processor from starting up, and prevents scheduling tasks.
This might be useful if you are experiencing performance issues or other problematic behaviour due to background task processing.
### `LD_DISABLE_URL_VALIDATION`
Values: `True`, `False` | Default = `False`
Completely disables URL validation for bookmarks.
This can be useful if you intend to store non fully qualified domain name URLs, such as network paths, or you want to store URLs that use another protocol than `http` or `https`.
### `LD_REQUEST_TIMEOUT`
Values: `Integer` as seconds | Default = `60`
Configures the request timeout in the uwsgi application server. This can be useful if you want to import a bookmark file with a high number of bookmarks and run into request timeouts.
### `LD_SERVER_HOST`
Values: Valid address for socket to bind to | Default = `[::]`
Allows to set a custom host for the UWSGI server running in the container. The default creates a dual stack socket, which will respond to IPv4 and IPv6 requests. IPv4 requests are logged as IPv4-mapped IPv6 addresses, such as "::ffff:127.0.0.1". If reverting to an IPv4-only socket is desired, this can be set to "0.0.0.0".
### `LD_SERVER_PORT`
Values: Valid port number | Default = `9090`
Allows to set a custom port for the UWSGI server running in the container. While Docker containers have their own IP address namespace and port collisions are impossible to achieve, there are other container solutions that share one. Podman, for example, runs all containers in a pod under one namespace, which results in every port only being allowed to be assigned once. This option allows to set a custom port in order to avoid collisions with other containers.
### `LD_CONTEXT_PATH`
Values: `String` | Default = None
Allows configuring the context path of the website. Useful for setting up Nginx reverse proxy.
The context path must end with a slash. For example: `linkding/`
### `LD_ENABLE_AUTH_PROXY`
Values: `True`, `False` | Default = `False`
Enables support for authentication proxies such as Authelia.
This effectively disables credentials-based authentication and instead authenticates users if a specific request header contains a known username.
You must make sure that your proxy (nginx, Traefik, Caddy, ...) forwards this header from your auth proxy to linkding. Check the documentation of your auth proxy and your reverse proxy on how to correctly set this up.
Note that this automatically creates new users in the database if they do not already exist.
Enabling this setting also requires configuring the following options:
- `LD_AUTH_PROXY_USERNAME_HEADER` - The name of the request header that the auth proxy passes to the proxied application (linkding in this case), so that the application can identify the user.
Check the documentation of your auth proxy to get this information.
Note that the request headers are rewritten in linkding: all HTTP headers are prefixed with `HTTP_`, all letters are in uppercase, and dashes are replaced with underscores.
For example, for Authelia, which passes the `Remote-User` HTTP header, the `LD_AUTH_PROXY_USERNAME_HEADER` needs to be configured as `HTTP_REMOTE_USER`.
- `LD_AUTH_PROXY_LOGOUT_URL` - The URL that linkding should redirect to after a logout.
By default, the logout redirects to the login URL, which means the user will be automatically authenticated again.
Instead, you might want to configure the logout URL of the auth proxy here.
### `LD_ENABLE_OIDC`
Values: `True`, `False` | Default = `False`
Enables support for OpenID Connect (OIDC) authentication, allowing to use single sign-on (SSO) with OIDC providers.
When enabled, this shows a button on the login page that allows users to authenticate using an OIDC provider.
Users are associated by the email address provided from the OIDC provider, which is used as the username in linkding.
If there is no user with that email address as username, a new user is created automatically.
This requires configuring a number of options, which of those you need depends on which OIDC provider you use and how it is configured.
In general, you should find the required information in the UI of your OIDC provider, or its documentation.
The options are adopted from the [mozilla-django-oidc](https://mozilla-django-oidc.readthedocs.io/en/stable/) library, which is used by linkding for OIDC support.
Please check their documentation for more information on the options.
The following options can be configured:
- `OIDC_OP_AUTHORIZATION_ENDPOINT` - The authorization endpoint of the OIDC provider.
- `OIDC_OP_TOKEN_ENDPOINT` - The token endpoint of the OIDC provider.
- `OIDC_OP_USER_ENDPOINT` - The user info endpoint of the OIDC provider.
- `OIDC_OP_JWKS_ENDPOINT` - The JWKS endpoint of the OIDC provider.
- `OIDC_RP_CLIENT_ID` - The client ID of the application.
- `OIDC_RP_CLIENT_SECRET` - The client secret of the application.
- `OIDC_RP_SIGN_ALGO` - The algorithm the OIDC provider uses to sign ID tokens. Default is `RS256`.
- `OIDC_USE_PKCE` - Whether to use PKCE for the OIDC flow. Default is `True`.
- `OIDC_VERIFY_SSL` - Whether to verify the SSL certificate of the OIDC provider. Set to `False` if using self-signed certificates or custom certificate authority. Default is `True`.
<details>
<summary>Authelia Example</summary>
#### Linkding Configuration
```bash
LD_ENABLE_OIDC=True
OIDC_OP_AUTHORIZATION_ENDPOINT=https://auth.example.com/api/oidc/authorization
OIDC_OP_TOKEN_ENDPOINT=https://auth.example.com/api/oidc/token
OIDC_OP_USER_ENDPOINT=https://auth.example.com/api/oidc/userinfo
OIDC_OP_JWKS_ENDPOINT=https://auth.example.com/jwks.json
OIDC_RP_CLIENT_ID=linkding
OIDC_RP_CLIENT_SECRET=myClientSecret
```
#### Authelia Configuration
```yaml
identity_providers:
oidc:
# --- more OIDC provider configuration ---
clients:
- id: linkding
description: Linkding
# docker run --rm authelia/authelia:latest authelia crypto rand --length 64 --charset alphanumeric
secret: myClientSecret
public: false
token_endpoint_auth_method: client_secret_post
scopes:
- openid
- email
- profile
redirect_uris:
- https://linkding.example.com/oidc/callback/
```
</details>
### `LD_CSRF_TRUSTED_ORIGINS`
Values: `String` | Default = None
List of trusted origins / host names to allow for `POST` requests, for example when logging in, or saving bookmarks.
For these type of requests, the `Origin` header must match the `Host` header, otherwise the request will fail with a `403` status code, and the message `CSRF verification failed.`
This option allows to declare a list of trusted origins that will be accepted even if the headers do not match. This can be the case when using a reverse proxy that rewrites the `Host` header, such as Nginx.
For example, to allow requests to https://linkding.mydomain.com, configure the setting to `https://linkding.mydomain.com`.
Note that the setting **must** include the correct protocol (`https` or `http`), and **must not** include the application / context path.
Multiple origins can be specified by separating them with a comma (`,`).
This setting is adopted from the Django framework used by linkding, more information on the setting is available in the [Django documentation](https://docs.djangoproject.com/en/4.0/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS).
### `LD_LOG_X_FORWARDED_FOR`
Values: `true` or `false` | Default = `false`
Set uWSGI [log-x-forwarded-for](https://uwsgi-docs.readthedocs.io/en/latest/Options.html?#log-x-forwarded-for) parameter allowing to keep the real IP of clients in logs when using a reverse proxy.
### `LD_DB_ENGINE`
Values: `postgres` or `sqlite` | Default = `sqlite`
Database engine used by linkding to store data.
Currently, linkding supports SQLite and PostgreSQL.
By default, linkding uses SQLite, for which you don't need to configure anything.
All the other database variables below are only required for configured PostgresSQL.
### `LD_DB_DATABASE`
Values: `String` | Default = `linkding`
The name of the database.
### `LD_DB_USER`
Values: `String` | Default = `linkding`
The name of the user to connect to the database server.
### `LD_DB_PASSWORD`
Values: `String` | Default = None
The password of the user to connect to the database server.
The password must be configured when using a database other than SQLite, there is no default value.
### `LD_DB_HOST`
Values: `String` | Default = `localhost`
The hostname or IP of the database server.
### `LD_DB_PORT`
Values: `Integer` | Default = None
The port of the database server.
Should use the default port if left empty, for example `5432` for PostgresSQL.
### `LD_DB_OPTIONS`
Values: `String` | Default = `{}`
A json string with additional options for the database. Passed directly to OPTIONS.
### `LD_FAVICON_PROVIDER`
Values: `String` | Default = `https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url={url}&size=32`
The favicon provider used for downloading icons if they are enabled in the user profile settings.
The default provider is a Google service that automatically detects the correct favicon for a website, and provides icons in consistent image format (PNG) and in a consistent image size.
This setting allows to configure a custom provider in form of a URL.
When calling the provider with the URL of a website, it must return the image data for the favicon of that website.
The configured favicon provider URL must contain a placeholder that will be replaced with the URL of the website for which to download the favicon.
The available placeholders are:
- `{url}` - Includes the scheme and hostname of the website, for example `https://example.com`
- `{domain}` - Includes only the hostname of the website, for example `example.com`
Which placeholder you need to use depends on the respective favicon provider, please check their documentation or usage examples.
See the default URL for how to insert the placeholder to the favicon provider URL.
Alternative favicon providers:
- DuckDuckGo: `https://icons.duckduckgo.com/ip3/{domain}.ico`
### `LD_SINGLEFILE_TIMEOUT_SEC`
Values: `Float` | Default = 60.0
When creating HTML archive snapshots, control the timeout for how long to wait for the snapshot to complete, in `seconds`.
Defaults to 60 seconds; on lower-powered hardware you may need to increase this value.
### `LD_SINGLEFILE_OPTIONS`
Values: `String` | Default = None
When creating HTML archive snapshots, pass additional options to the `single-file` application that is used to create snapshots.
See `single-file --help` for complete list of arguments, or browse source: https://github.com/gildas-lormeau/single-file-cli/blob/master/options.js
Example: `LD_SINGLEFILE_OPTIONS=--user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:124.0) Gecko/20100101 Firefox/124.0"`

View File

@@ -0,0 +1,13 @@
---
title: "Keyboard Shortcuts"
description: "Keyboard Shortcuts"
---
The following keyboard shortcuts are currently available:
| Action | Shortcut |
|-------------------------------------------------------------------------------------------|-------------------------------------|
| Add new bookmark | <kbd>n</kbd> |
| Focus search input | <kbd>s</kbd> |
| Navigate bookmarks | <kbd></kbd>, <kbd></kbd> |
| Toggle bookmark notes | <kbd>e</kbd> |

View File

@@ -0,0 +1,21 @@
---
title: "Troubleshooting"
description: "Common issues and solutions"
---
## Login fails with `403 CSRF verfication failed`
This can be the case when using a reverse proxy that rewrites the `Host` header, such as Nginx.
Since linkding version 1.15, the application includes a CSRF check that verifies that the `Origin` request header matches the `Host` header.
If the `Host` header is modified by the reverse proxy then this check fails.
To fix this, check the [reverse proxy setup documentation](/installation#reverse-proxy-setup) on how to configure header forwarding for your proxy server, or alternatively configure the [`LD_CSRF_TRUSTED_ORIGINS` option](/options#ld_csrf_trusted_origins) to the URL from which you are accessing your linkding instance.
## Import fails with `502 Bad Gateway`
The default timeout for requests is 60 seconds, after which the application server will cancel the request and return the above error.
Depending on the system that the application runs on, and the number of bookmarks that need to be imported, the import may take longer than the default 60 seconds.
To increase the timeout you can configure the [`LD_REQUEST_TIMEOUT` option](/options#ld_request_timeout).
Note that any proxy servers that you are running in front of linkding may have their own timeout settings, which are not affected by the variable.

2
docs/src/env.d.ts vendored Normal file
View File

@@ -0,0 +1,2 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />

View File

@@ -0,0 +1,16 @@
:root[data-theme='light'],
[data-theme='light'] ::backdrop {
--sl-color-accent: hsl(241, 63%, 59%);
--sl-color-text-accent: hsl(241, 63%, 55%);
--sl-nav-gap: 0.8rem;
}
/* Align site search */
.header .title-wrapper + div.sl-flex {
justify-content: flex-end;
}
.site-title img {
height: 36px;
}