Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ export function useNotebookActions() {
{
icon: <MarimoPlusIcon size={14} strokeWidth={1.5} />,
label: "Create molab notebook",
hidden: !sharingWasmEnabled,
handle: async () => {
const code = await readCode();
const url = createShareableLink({
Expand Down
50 changes: 28 additions & 22 deletions frontend/src/components/static-html/static-banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useAtomValue } from "jotai";
import { CopyIcon, DownloadIcon } from "lucide-react";
import type React from "react";
import { Constants } from "@/core/constants";
import { useResolvedMarimoConfig } from "@/core/config/config";
import { codeAtom } from "@/core/saving/file-state";
import { useFilename } from "@/core/saving/filename";
import { isStaticNotebook } from "@/core/static/static-state";
Expand Down Expand Up @@ -66,6 +67,9 @@ const StaticBannerDialog = ({ code }: { code: string }) => {
filename = filename.slice(lastSlash + 1);
}

const [resolvedConfig] = useResolvedMarimoConfig();
const molabEnabled = resolvedConfig.sharing?.wasm !== false;

const href = window.location.href;
const molabLink = createShareableLink({
code,
Expand Down Expand Up @@ -118,28 +122,30 @@ const StaticBannerDialog = ({ code }: { code: string }) => {
</div>
)}

<div className="pt-3 border-t flex gap-2 items-center">
<Button
asChild={true}
variant="outline"
size="xs"
className="shrink-0"
>
<a href={molabLink} target="_blank" rel="noopener noreferrer">
<MarimoPlusIcon
size={12}
strokeWidth={1.5}
className="mr-1.5 mt-px text-(--grass-11)"
/>
Open in molab
</a>
</Button>
<p className="text-sm text-(--sky-12)">
Run this notebook in{" "}
<span className="font-semibold">molab</span>, marimo's
cloud-hosted notebook platform.
</p>
</div>
{molabEnabled && (
<div className="pt-3 border-t flex gap-2 items-center">
<Button
asChild={true}
variant="outline"
size="xs"
className="shrink-0"
>
<a href={molabLink} target="_blank" rel="noopener noreferrer">
<MarimoPlusIcon
size={12}
strokeWidth={1.5}
className="mr-1.5 mt-px text-(--grass-11)"
/>
Open in molab
</a>
</Button>
<p className="text-sm text-(--sky-12)">
Run this notebook in{" "}
<span className="font-semibold">molab</span>, marimo's
cloud-hosted notebook platform.
</p>
</div>
)}
</DialogDescription>
</DialogHeader>
<div className="flex gap-3 pt-2">
Expand Down
4 changes: 3 additions & 1 deletion marimo/_server/api/endpoints/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,13 @@ async def export_as_html(
if not app_state.session_manager.should_send_code_to_frontend():
body.include_code = False

resolved_config = session.config_manager.get_config()
html, filename = Exporter().export_as_html(
app=session.app_file_manager.app,
filename=session.app_file_manager.filename,
session_view=session.session_view,
display_config=session.config_manager.get_config()["display"],
display_config=resolved_config["display"],
sharing_config=resolved_config.get("sharing"),
request=body,
)

Expand Down
12 changes: 9 additions & 3 deletions marimo/_server/export/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,17 @@ def export_as_wasm(
# Inline the layout file, if it exists
app.inline_layout_file()
config = get_default_config_manager(current_path=path.absolute_name)
resolved = config.get_config()

result = Exporter().export_as_wasm(
filename=path.short_name,
app=app,
display_config=config.get_config()["display"],
display_config=resolved["display"],
mode=mode,
code=app.to_py(),
asset_url=asset_url,
show_code=show_code,
sharing_config=resolved.get("sharing"),
)
return ExportResult(
contents=result[0],
Expand Down Expand Up @@ -332,7 +334,8 @@ async def run_app_then_export_as_html(
file_manager.app.inline_layout_file()

config = get_default_config_manager(current_path=file_manager.path)
display_config = cast(DisplayConfig, config.get_config()["display"])
resolved = config.get_config()
display_config = cast(DisplayConfig, resolved["display"])
session_view, did_error = await run_app_until_completion(
file_manager,
cli_args,
Expand All @@ -344,6 +347,7 @@ async def run_app_then_export_as_html(
app=file_manager.app,
session_view=session_view,
display_config=display_config,
sharing_config=resolved.get("sharing"),
request=ExportAsHTMLRequest(
include_code=include_code,
download=False,
Expand Down Expand Up @@ -377,7 +381,8 @@ async def run_app_then_export_as_wasm(
file_manager.app.inline_layout_file()

config = get_default_config_manager(current_path=file_manager.path)
display_config = cast(DisplayConfig, config.get_config()["display"])
resolved = config.get_config()
display_config = cast(DisplayConfig, resolved["display"])

session_view, did_error = await run_app_until_completion(
file_manager,
Expand Down Expand Up @@ -406,6 +411,7 @@ async def run_app_then_export_as_wasm(
asset_url=asset_url,
session_snapshot=session_snapshot,
notebook_snapshot=notebook_snapshot,
sharing_config=resolved.get("sharing"),
)
return ExportResult(
contents=html,
Expand Down
23 changes: 12 additions & 11 deletions marimo/_server/export/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
DEFAULT_CONFIG,
DisplayConfig,
MarimoConfig,
SharingConfig,
)
from marimo._config.settings import GLOBAL_SETTINGS
from marimo._config.utils import deep_copy
Expand Down Expand Up @@ -101,12 +102,13 @@ def export_as_html(
session_view: SessionView,
display_config: DisplayConfig,
request: ExportAsHTMLRequest,
sharing_config: SharingConfig | None = None,
) -> tuple[str, str]:
index_html = get_html_contents()
filename = get_filename(filename)

# Configure notebook with display settings
config = self._prepare_display_config(display_config)
# Configure notebook with display and sharing settings
config = self._prepare_display_config(display_config, sharing_config)

# Serialize notebook state
session_snapshot = serialize_session_view(
Expand Down Expand Up @@ -157,15 +159,15 @@ def export_as_html(
return html, download_filename

def _prepare_display_config(
self, display_config: DisplayConfig
self,
display_config: DisplayConfig,
sharing_config: SharingConfig | None = None,
) -> MarimoConfig:
"""Prepare config with display settings for static notebook."""
# We only want pass the display config in the static notebook,
# since we use:
# - display.theme
# - display.cell_output
"""Prepare config with display and sharing settings for static notebook."""
config = deep_copy(DEFAULT_CONFIG)
config["display"] = display_config
if sharing_config:
config["sharing"] = sharing_config # type: ignore[typeddict-item]
return cast(MarimoConfig, config)

def _inline_virtual_files(
Expand Down Expand Up @@ -349,14 +351,13 @@ def export_as_wasm(
asset_url: str | None = None,
session_snapshot: NotebookSessionV1 | None = None,
notebook_snapshot: NotebookV1 | None = None,
sharing_config: SharingConfig | None = None,
) -> tuple[str, str]:
"""Export notebook as a WASM-powered standalone HTML file."""
index_html = get_html_contents()
filename = get_filename(filename)

# We only want to pass the display config in the static notebook
config: MarimoConfig = deep_copy(DEFAULT_CONFIG)
config["display"] = display_config
config = self._prepare_display_config(display_config, sharing_config)
# Remove autosave
config["save"]["autosave"] = "off"

Expand Down
Loading