diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..b38d80584
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,16 @@
+# Changelog
+
+Significant changes to DocumentCloud's frontend will be noted in this file. We also announce new features in MuckRock's regular [Release Notes](https://www.muckrock.com/news/archives/?tags=115608) column.
+
+DocumentCloud is a running application used by thousands of journalists around the world, so updates here are organized by date, not by version number. The goal of this file is to keep a record of features added, updated and removed.
+
+## 2024-12-02 DocumentCloud on SvelteKit released
+
+This is the latest iteration of DocumentCloud, bringing the frontend to SvelteKit and updating the UI.
+
+Our goals:
+
+- Clean up the user interface to provide a consistent experience that scales across devices.
+- Server-render pages, making them faster to load and easier to share.
+- Simplify the application’s logic to make it easier to reason about its structure, reactivity and state, and make it easier to support new features.
+- Modernize our technologies and development practices to speed up development, ensuring high-quality, bug free code from the start.
diff --git a/src/hooks.server.ts b/src/hooks.server.ts
index 2108c89ca..1ed6a4643 100644
--- a/src/hooks.server.ts
+++ b/src/hooks.server.ts
@@ -33,10 +33,13 @@ export const handleError = Sentry.handleErrorWithSentry();
/** @type {import('@sveltejs/kit').Handle} */
async function language({ event, resolve }) {
const lang =
- event.request.headers.get("accept-language")?.split(",")[0] ?? "en-US";
+ event.request.headers.get("accept-language")?.split(",")[0] ?? "en";
- if (lang) {
- locale.set(lang);
+ // use en.json for en-US and such
+ const [language, ...tags] = lang.split("-");
+
+ if (language) {
+ locale.set(language);
}
return resolve(event, {
diff --git a/src/langs/json/en.json b/src/langs/json/en.json
index 0ec1235fb..ff6681be9 100644
--- a/src/langs/json/en.json
+++ b/src/langs/json/en.json
@@ -11,7 +11,10 @@
"title": "Title"
},
"search": {
- "matchingResults": "{n, plural, one {# matching result} other {# matching results}}"
+ "matchingResults": "{n, plural, one {# matching result} other {# matching results}}",
+ "reset": "Clear Search",
+ "help": "Use filters like user:
, project:
or organization:
to refine searches. Use sort:
to order results.",
+ "more": "Learn more"
},
"homeTemplate": {
"signedIn": "Signed in as {name}",
@@ -203,7 +206,9 @@
"pageAbbrev": "p.",
"pageCount": "{n, plural, one {# page} other {# pages}}",
"select": "Select",
- "noteCount": "{n, plural, one {# note} other {# notes}}"
+ "noteCount": "{n, plural, one {# note} other {# notes}}",
+ "more": "Load more",
+ "retry": "Please try again."
},
"error": {
"report": "Report a problem"
@@ -247,7 +252,7 @@
"view": "Viewer"
},
"delete": {
- "action": "Delete project",
+ "action": "Delete Project",
"confirm": "Confirm delete",
"really": "Are you sure you want to delete this project ({project})?"
},
@@ -258,7 +263,7 @@
"collaborators": {
"title": "Collaborators",
"empty": "No collaborators",
- "add": "Invite users to this project"
+ "add": "Invite"
},
"fields": {
"title": "Title",
@@ -345,15 +350,18 @@
"shareEmbed": "Share & Embed",
"sharedWith": "Shared with",
"revisions": "Revision History",
- "edit": "Edit Metadata",
+ "edit": "Edit Document Metadata",
"upload": "Upload Documents",
"uploadToProject": "Upload to Project",
"download": "Download File",
"reprocess": "Reprocess",
+ "delete": "Delete",
+ "shareEmbedProject": "Share & Embed Project",
+ "editProject": "Edit Project Metadata",
+ "deleteProject": "Delete Project",
"created": "Created on",
"updated": "Last updated on",
"language": "Language",
- "delete": "Delete",
"ocr_engine": "OCR Engine",
"addons": {
"title": "Add-Ons",
@@ -382,7 +390,7 @@
"cta": "Annotate this document"
},
"edit": {
- "title": "Edit document metadata",
+ "title": "Edit Document Metadata",
"fields": {
"title": "Title",
"description": "Description",
@@ -417,10 +425,10 @@
}
},
"redact": {
+ "title": "Redact Document",
"confirm": "Save",
"confirmTitle": "Save Redactions",
"really": "Are you sure you wish to redact the current document? If you continue, the document viewer will be inaccessible temporarily while the document reprocesses with the redactions in place. This change is irreversible.",
- "title": "Redact Document",
"instructions": "Click and drag to draw a black rectangle over each portion of the document you’d like to redact. Associated text will be removed when you save your redactions.",
"undo": "Undo",
"cancel": "Discard",
@@ -432,13 +440,13 @@
"page": "Page",
"title": "Title",
"delete": "Delete",
- "new": "Add a new section",
+ "new": "Add New Section",
"clear": "Clear",
"update": "Update section",
"overwrite": "There is already a section starting on page {n}."
},
"delete": {
- "title": "Confirm delete",
+ "title": "Confirm Delete",
"really": "Proceeding will permanently delete the {n, plural, one {selected document} other {# selected documents}}.",
"continue": "Do you wish to continue?",
"confirm": "Delete",
@@ -447,7 +455,7 @@
"none": "No documents selected. Close this form and select at least one document first."
},
"data": {
- "title": "Edit tags and data",
+ "title": "Edit Tags & Data",
"key": "Key",
"newkey": "New item",
"value": "Value",
@@ -457,15 +465,15 @@
"save": "Save",
"cancel": "Cancel",
"addNew": "Add new item:",
- "many": "Saving will add the following data and tags to {n, plural, one {the selected document} other {all # selected documents}}. No tags or data will be removed."
+ "many": "Saving will add the following tags and data to {n, plural, one {the selected document} other {all # selected documents}}. No tags or data will be removed."
},
"bulk": {
- "title": "Edit",
+ "title": "Actions",
"actions": {
- "share": "Share",
- "edit": "Edit metadata",
- "data": "Edit tags & data",
- "project": "Move to project",
+ "share": "Share & Embed",
+ "edit": "Edit Metadata",
+ "data": "Edit Tags & Data",
+ "project": "Move to Project",
"reprocess": "Reprocess",
"delete": "Delete"
}
diff --git a/src/lib/api/types.d.ts b/src/lib/api/types.d.ts
index 7fb28597b..bef902f0f 100644
--- a/src/lib/api/types.d.ts
+++ b/src/lib/api/types.d.ts
@@ -1,9 +1,7 @@
/**
* API response types
- *
- * This is a separate module from what's in src/api to prevent conflicts.
- * Both modules can be merged later.
- * */
+ */
+
import type { DefinedError } from "ajv";
export type Access = "public" | "private" | "organization"; // https://www.documentcloud.org/help/api#access-levels
diff --git a/src/lib/components/accounts/tests/__snapshots__/UserMenu.test.ts.snap b/src/lib/components/accounts/tests/__snapshots__/UserMenu.test.ts.snap
index d6f245ae9..e3e6ba138 100644
--- a/src/lib/components/accounts/tests/__snapshots__/UserMenu.test.ts.snap
+++ b/src/lib/components/accounts/tests/__snapshots__/UserMenu.test.ts.snap
@@ -9,7 +9,7 @@ exports[`UserMenu 1`] = `
tabindex="0"
>