diff --git a/apps/web/src/utils/web-extension-server.ts b/apps/web/src/utils/web-extension-server.ts
index e88460f83..d5cd96fc4 100644
--- a/apps/web/src/utils/web-extension-server.ts
+++ b/apps/web/src/utils/web-extension-server.ts
@@ -73,7 +73,11 @@ export class WebExtensionServer implements Server {
async saveClip(clip: Clip) {
let clipContent = "";
- if (clip.mode === "simplified" || clip.mode === "screenshot") {
+ if (
+ clip.mode === "simplified" ||
+ clip.mode === "screenshot" ||
+ clip.mode === "bookmark"
+ ) {
clipContent += clip.data;
} else {
const clippedFile = new File(
@@ -105,11 +109,17 @@ export class WebExtensionServer implements Server {
if (isCipher(content)) return;
content += clipContent;
- content += h("div", [
- h("hr"),
- h("p", ["Clipped from ", h("a", [clip.title], { href: clip.url })]),
- h("p", [`Date clipped: ${getFormattedDate(Date.now())}`])
- ]).innerHTML;
+ content +=
+ clip.mode === "bookmark"
+ ? h("div", [
+ h("p", [`Date bookmarked: ${getFormattedDate(Date.now())}`]),
+ h("hr")
+ ]).innerHTML
+ : h("div", [
+ h("hr"),
+ h("p", ["Clipped from ", h("a", [clip.title], { href: clip.url })]),
+ h("p", [`Date clipped: ${getFormattedDate(Date.now())}`])
+ ]).innerHTML;
const id = await db.notes.add({
id: note?.id,
diff --git a/docs/help/contents/web-clipper/clipping-your-first-web-page-with-web-clipper.md b/docs/help/contents/web-clipper/clipping-your-first-web-page-with-web-clipper.md
index 9e83b332c..4ae5f967f 100644
--- a/docs/help/contents/web-clipper/clipping-your-first-web-page-with-web-clipper.md
+++ b/docs/help/contents/web-clipper/clipping-your-first-web-page-with-web-clipper.md
@@ -73,6 +73,10 @@ The `Selected nodes` mode allows you to select exactly which nodes you want to c
The clipping mode controls how the final clip should look.
+### Bookmark
+
+`Bookmark` mode saves only the URL of the page along with the title. It is best suited to save pages for later reading/reference.
+
### Simplified
`Simplified` mode doesn't include any styles. It is best suited for long-form content such as articles & blogs. All clips in `Simplified` mode are saved directly as is i.e. they do not appear as web clip embeds in the Notesnook editor.
diff --git a/extensions/web-clipper/src/common/bridge.ts b/extensions/web-clipper/src/common/bridge.ts
index 3e081fb62..894c76fae 100644
--- a/extensions/web-clipper/src/common/bridge.ts
+++ b/extensions/web-clipper/src/common/bridge.ts
@@ -21,7 +21,7 @@ import { ThemeDefinition } from "@notesnook/theme";
export type ClipArea = "full-page" | "visible" | "selection" | "article";
-export type ClipMode = "simplified" | "screenshot" | "complete";
+export type ClipMode = "bookmark" | "simplified" | "screenshot" | "complete";
export type User = {
email?: string;
diff --git a/extensions/web-clipper/src/components/icons/index.ts b/extensions/web-clipper/src/components/icons/index.ts
index ee1f97e76..bba876573 100644
--- a/extensions/web-clipper/src/components/icons/index.ts
+++ b/extensions/web-clipper/src/components/icons/index.ts
@@ -57,6 +57,7 @@ export const Icons = {
visible: mdiViewDayOutline,
selection: mdiCursorDefaultClickOutline,
+ bookmark: mdiBookmarkOutline,
simplified: mdiTextBoxOutline,
screenshot: mdiFitToScreenOutline,
complete: mdiViewDashboardOutline,
diff --git a/extensions/web-clipper/src/views/main.tsx b/extensions/web-clipper/src/views/main.tsx
index 80b0de2a3..8f99a1d32 100644
--- a/extensions/web-clipper/src/views/main.tsx
+++ b/extensions/web-clipper/src/views/main.tsx
@@ -68,6 +68,11 @@ const clipAreas: { name: string; id: ClipArea; icon: string }[] = [
const clipModes: { name: string; id: ClipMode; icon: string; pro?: boolean }[] =
[
+ {
+ name: "Bookmark",
+ id: "bookmark",
+ icon: Icons.bookmark
+ },
{
name: "Simplified",
id: "simplified",
@@ -166,7 +171,7 @@ export function Main() {
}, [settings]);
async function startClip() {
- if (!clipArea || !clipMode) return;
+ if (!clipArea || !clipMode || clipMode === "bookmark") return;
try {
setError(undefined);
@@ -268,7 +273,11 @@ export function Main() {
setClipperState(ClipperState.Idle);
setClipArea(item.id);
}}
- disabled={isClipping || clipperState === ClipperState.Clipped}
+ disabled={
+ isClipping ||
+ clipperState === ClipperState.Clipped ||
+ clipMode === "bookmark"
+ }
sx={{
display: "flex",
borderRadius: "default",
@@ -342,55 +351,58 @@ export function Main() {
))}
- {clipData && clipData.data && !isClipping && (
-
- {
- const winUrl = URL.createObjectURL(
- new Blob(["\ufeff", clipData.data], { type: "text/html" })
- );
- await browser.windows.create({
- url: winUrl
- });
- }}
- >
- Clip done. Click here to preview.
-
- {
- setClipData(undefined);
- setClipperState(ClipperState.Idle);
- }}
- >
- Discard
-
-
- )}
+ {clipMode !== "bookmark" &&
+ clipData &&
+ clipData.data &&
+ !isClipping && (
+
+ {
+ const winUrl = URL.createObjectURL(
+ new Blob(["\ufeff", clipData.data], { type: "text/html" })
+ );
+ await browser.windows.create({
+ url: winUrl
+ });
+ }}
+ >
+ Clip done. Click here to preview.
+
+ {
+ setClipData(undefined);
+ setClipperState(ClipperState.Idle);
+ }}
+ >
+ Discard
+
+
+ )}
{error && (
{
if (
- clipperState === ClipperState.Idle ||
- clipperState === ClipperState.Error
+ clipMode !== "bookmark" &&
+ (clipperState === ClipperState.Idle ||
+ clipperState === ClipperState.Error)
) {
await startClip();
return;
}
- if (!clipData || !title || !clipArea || !clipMode || !url) return;
+ if (!title || !clipArea || !clipMode || !url) return;
+
+ const data =
+ clipMode === "bookmark"
+ ? {
+ data: createBookmark(url, title)
+ }
+ : clipData;
+
+ if (!data) return;
const notesnook = await connectApi(false);
if (!notesnook) {
@@ -476,7 +498,7 @@ export function Main() {
note,
refs,
pageTitle: pageTitle.current,
- ...clipData
+ ...data
});
setClipData(undefined);
@@ -492,7 +514,9 @@ export function Main() {
window.close();
}}
>
- {clipperButtonLabelMap[clipperState]}
+ {clipMode === "bookmark"
+ ? "Save bookmark"
+ : clipperButtonLabelMap[clipperState]}