Live Demo · Screenshots · Features · Getting Started
Table of Contents
-
Authentication: log in via any OIDC compliant Solid identity provider (
solidcommunity.net,inrupt.net,solidweb.org, or a self hosted server) -
Layout choice: switch at runtime between the classic two pane shell and the OneDrive style shell; the preference is persisted in
localStorage -
Language switching: switch between English and German at runtime
-
OneDrive views: Home / Recent, My Files, Shared, Requests, and People; each view has its own toolbar, type filter chips, and a person and name filter; the Shared view has With you and By you tabs
-
Pod navigation: browse the full Pod directory tree with breadcrumb navigation; per folder scroll position is preserved across browser back and forward
-
URLs and history: the open folder is reflected in the query string (
folder=…) and the active OneDrive view inview=…; copy the address bar to share a deep link, and use the browser back/forward buttons to move through your navigation history
-
File upload: accepts any file type. Users can upload through the dialog form, by dragging files onto the panel or a folder row, or from the OneDrive Create menu. The binary and a metadata document
index.ttlare stored inside a dedicated container on the Pod, and an upload tray surfaces progress and per file retry. -
Folder creation: the classic explorer uses an inline form, and the OneDrive shell opens a modal dialog. Both create LDP BasicContainers under the active folder.
-
File adoption: renders files that existed on the Pod before the app was used, showing folder name and download button for containers lacking
index.ttl -
Inline preview: images, videos, audio, PDFs, and text files preview directly in the browser, no request leaves the browser after the file is fetched
-
Download: triggers a browser native download from the blob URL
-
File info: a toggle on each file card shows type, size, upload date, modified date, and publisher name resolved from their Solid profile
-
Selection actions: the OneDrive shell shows Share, Copy link, Delete, and Download in the page header, plus Move to and Rename stubs. Actions that no longer fit inline spill into a kebab dropdown at narrow viewports.
-
Delete: removes the binary,
index.ttl, the container, and the catalog entry; no orphaned resources remain
-
TBox-driven validation: SHACL shapes are loaded from
public/tbox.ttlat form open time; required fields (name,uploadDate,publisher) are enforced before upload; missing fields are surfaced inline -
Semantic classification: MIME type is mapped to a schema.org class and written to
index.ttlasrdf:type -
Catalog management:
catalog.ttlis updated on every upload and cleaned up on every delete using SPARQL PATCH
-
Share / revoke access: each owned file can be shared with contacts from the user’s Solid profile; ACLs and per contact shared catalogs are kept in sync
-
Shared with Me: reads per contact shared catalogs first, then falls back to the contact’s main catalog
-
Filtered system files: internal catalog and ACL helper files (
.shared-*.ttl) are hidden from the normal file browser
| Layer | Libraries / tools |
|---|---|
Frontend |
React 19 · TypeScript · Vite |
Solid / Linked Data |
@ldo/solid · @ldo/solid-react · ShEx · schema.org · DCAT · SHACL |
Internationalisation |
i18next · react-i18next · i18next-browser-languagedetector |
Testing |
Vitest · @testing-library/react · jsdom · Playwright (E2E) |
CI |
GitHub Actions (test coverage · Playwright · Docker) |
Deployment |
Docker · nginx |
npm test # unit tests once
npm run test:watch # unit tests in watch mode
npm run test:coverage # unit tests with v8 coverage
npm run test:e2e # Playwright end-to-end tests
npm run test:e2e:ui # Playwright interactive UI modenpm run build # extract TBox, type check, and bundle
npm run preview # serve the built bundle locallynpm run tbox:extract # refetch datashapes.org and rewrite public/tbox.ttl
npm run build:ldo # recompile ShEx shapes -> TypeScript bindings in src/.ldo/|
ℹ️
|
npm run dev and npm run build run tbox:extract automatically. Use the manual commands only after editing .shapes/ files or when the upstream ontology changes.
|
Run the published image:
docker run -p 40211:80 wseresearch/solid-hello-world-frontend-reactOr build and run locally:
docker build -t wseresearch/solid-hello-world-frontend-react:local .
docker run -p 40211:80 wseresearch/solid-hello-world-frontend-react:localThe app listens on port 80 inside the container; open http://localhost:5173/ in your browser.
Each uploaded file gets a dedicated container on the Pod. A DCAT catalog at the storage root keeps a queryable index:
Pod storage root/
|-- catalog.ttl <- DCAT catalog: one entry per file
`-- my-solid-app/
|-- .shared-<webid>.ttl <- per-contact shared catalog
`-- photo-2024-01-01/ <- one container per uploaded file
|-- photo.jpg <- the binary
`-- index.ttl <- schema.org metadata
pick file
-> validate metadata against SHACL shapes (tbox.ttl)
-> resolve schema.org class from MIME type
-> create container
-> upload binary
-> write index.ttl
-> append dcat:Dataset entry to catalog.ttl
-> link catalog to WebID profile (first upload only)
|
ℹ️
|
If any step after the binary upload fails, the whole container is deleted, no half written resources are left on the Pod. |
Sharing happens at the file container level.
Granting access updates the file’s ACL and mirrors its catalog entry into a per contact shared catalog inside my-solid-app/.
Revoking removes the recipient from the ACL and cleans up their shared catalog entry.
MIME types are mapped to schema.org classes:
image/*-
schema:ImageObject video/*-
schema:VideoObject audio/*-
schema:AudioObject text/*,application/pdf, Word-
schema:TextDigitalDocument - CSV, Excel
-
schema:SpreadsheetDigitalDocument - Anything else
-
schema:DigitalDocument
solid.drive/ |-- src/ | |-- .shapes/ # ShEx shapes (edit here) | |-- .ldo/ # LDO bindings (auto generated) | |-- app/ # Root component, ClassicLayout, bootstrap hooks, i18n, locales | |-- config/ # Constants and env vars | |-- features/ | | |-- auth/ | | |-- file-explorer/ | | |-- onedrive-layout/ # OneDrive style shell: rail, top bar, views, hooks | | |-- profile/ | | `-- sharing/ # WAC/ACL hooks | |-- infrastructure/ # Solid/RDF, no React | | |-- inbox/ | | |-- solid/ | | |-- validation/ | | `-- wac/ | |-- shared/ # Components, contexts, hooks, utils | |-- types/ | `-- assets/ |-- public/ | `-- tbox.ttl # SHACL TBox (auto generated) |-- scripts/ |-- e2e/ # Playwright tests |-- .github/workflows/ # CI: test coverage, Playwright, Docker |-- Dockerfile |-- nginx.conf |-- vite.config.ts `-- vitest.config.ts
See src/README.adoc for the full layer map and dependency rules.
See src/.shapes/README.adoc for shape definitions.
See TESTER_GUIDE.adoc for manual QA steps.
-
inrupt.netblocks localhost redirects. The inrupt.net identity provider rejects OIDC redirect URIs pointing tolocalhost. Usesolidcommunity.netorsolidweb.orgwhen testing locally.
Contributions are welcome. Open a new issue to discuss a change, or send a pull request directly.
Before submitting, please:
-
Run
npm run lint,npm test, andnpm run test:e2elocally. -
Keep coverage above the configured 80% thresholds.
-
Follow the per directory module convention (
-file/,-test/,index-test/,README.adoc).
Released under the MIT License © Web & Software Engineering research group, Leipzig University of Applied Sciences.