or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-routing.mdauthentication.mdcss-styling.mddevelopment-tools.mdform-handling.mdhtml-components.mdhtmx-integration.mdindex.mdjavascript-integration.mdnotifications.mdsvg-components.md

javascript-integration.mddocs/

0

# JavaScript Integration

1

2

Integration with popular JavaScript libraries including Markdown rendering, syntax highlighting, interactive components, and client-side scripting utilities.

3

4

## Capabilities

5

6

### JavaScript Library Integration

7

8

Pre-configured JavaScript library loaders for popular front-end libraries.

9

10

```python { .api }

11

def MarkdownJS(*c, **kw):

12

"""

13

Markdown parsing and rendering.

14

15

Integrates markdown-it library for client-side markdown

16

parsing and HTML rendering.

17

18

Args:

19

*c: Content or configuration

20

**kw: Library configuration options

21

22

Returns:

23

Script elements for markdown functionality

24

"""

25

26

def KatexMarkdownJS(*c, **kw):

27

"""

28

Markdown with KaTeX math support.

29

30

Combines markdown parsing with KaTeX for mathematical

31

formula rendering in markdown content.

32

33

Args:

34

*c: Content or configuration

35

**kw: Library and math rendering options

36

37

Returns:

38

Script elements for markdown with math support

39

"""

40

41

def HighlightJS(*c, **kw):

42

"""

43

Syntax highlighting.

44

45

Integrates highlight.js for syntax highlighting

46

of code blocks in various programming languages.

47

48

Args:

49

*c: Configuration or language specifications

50

**kw: Highlighting options and themes

51

52

Returns:

53

Script and style elements for syntax highlighting

54

"""

55

56

def SortableJS(*c, **kw):

57

"""

58

Drag-and-drop sorting.

59

60

Integrates SortableJS for drag-and-drop functionality

61

on lists and grid elements.

62

63

Args:

64

*c: Configuration options

65

**kw: Sortable behavior settings

66

67

Returns:

68

Script elements for drag-and-drop functionality

69

"""

70

71

def MermaidJS(*c, **kw):

72

"""

73

Diagram and flowchart rendering.

74

75

Integrates Mermaid.js for rendering diagrams,

76

flowcharts, and other visualizations from text.

77

78

Args:

79

*c: Diagram definitions or configuration

80

**kw: Rendering options and themes

81

82

Returns:

83

Script elements for diagram rendering

84

"""

85

```

86

87

### Client-Side Scripting Utilities

88

89

Enhanced JavaScript execution and client-side scripting capabilities.

90

91

```python { .api }

92

def Surreal(*c, **kw):

93

"""

94

Surreal JavaScript code block.

95

96

Creates Surreal.js code blocks for enhanced DOM

97

manipulation and client-side interactions.

98

99

Args:

100

*c: Surreal.js code content

101

**kw: Script attributes and options

102

103

Returns:

104

Script element with Surreal.js code

105

"""

106

107

def On(*c, **kw):

108

"""

109

Event handler JavaScript.

110

111

Creates JavaScript event handlers with simplified

112

syntax for DOM events.

113

114

Args:

115

*c: Event handler code

116

**kw: Event options and attributes

117

118

Returns:

119

JavaScript code for event handling

120

"""

121

122

def Prev(*c, **kw):

123

"""

124

Previous element event handler.

125

126

Creates event handlers that target the previous

127

sibling element in the DOM.

128

129

Args:

130

*c: Handler code

131

**kw: Event configuration

132

133

Returns:

134

JavaScript code for previous element targeting

135

"""

136

137

def Now(*c, **kw):

138

"""

139

Immediate JavaScript execution.

140

141

Executes JavaScript code immediately when the

142

element is rendered.

143

144

Args:

145

*c: JavaScript code to execute

146

**kw: Execution options

147

148

Returns:

149

Script element with immediate execution

150

"""

151

152

def AnyNow(*c, **kw):

153

"""

154

JavaScript execution on any element.

155

156

Executes JavaScript code on any matching element

157

when rendered or modified.

158

159

Args:

160

*c: JavaScript code

161

**kw: Element selection and execution options

162

163

Returns:

164

Script element with flexible execution

165

"""

166

167

def run_js(code: str):

168

"""

169

Execute JavaScript code.

170

171

Executes JavaScript code in the browser context

172

with proper error handling.

173

174

Args:

175

code: JavaScript code to execute

176

177

Returns:

178

Script element with code execution

179

"""

180

```

181

182

### CDN Library Loading

183

184

Utility for loading JavaScript libraries from CDN services.

185

186

```python { .api }

187

def jsd(library: str, version: str = None, **kwargs):

188

"""

189

JavaScript library loader from CDN.

190

191

Loads JavaScript libraries from jsDelivr CDN with

192

version management and dependency handling.

193

194

Args:

195

library: Library name (e.g., 'jquery', 'lodash')

196

version: Specific version to load (latest if None)

197

**kwargs: Additional loading options

198

199

Returns:

200

Script element with CDN library loading

201

"""

202

```

203

204

### Surreal.js Client-Side Scripting

205

206

Surreal.js integration for DOM manipulation and event handling without traditional JavaScript syntax.

207

208

```python { .api }

209

def Surreal(code: str):

210

"""

211

Wrap JavaScript code in Surreal.js domReadyExecute.

212

213

Args:

214

code: JavaScript code to execute when DOM is ready

215

216

Returns:

217

Script element with Surreal.js DOM ready wrapper

218

"""

219

220

def On(code: str, event='click', sel='', me=True):

221

"""

222

Event handler with Surreal.js syntax.

223

224

Args:

225

code: JavaScript code to execute on event

226

event: DOM event type (click, submit, etc.)

227

sel: CSS selector for target elements

228

me: Whether to include 'me' context

229

230

Returns:

231

Surreal.js event handler script

232

"""

233

234

def Prev(code: str, event='click'):

235

"""

236

Event handler on previous sibling element.

237

238

Args:

239

code: JavaScript code to execute

240

event: DOM event type

241

242

Returns:

243

Surreal.js previous sibling event handler

244

"""

245

246

def Now(code: str, sel=''):

247

"""

248

Execute JavaScript immediately on page load.

249

250

Args:

251

code: JavaScript code to execute

252

sel: CSS selector for context

253

254

Returns:

255

Immediate execution script

256

"""

257

258

def AnyNow(sel: str, code: str):

259

"""

260

Execute JavaScript on any selector match.

261

262

Args:

263

sel: CSS selector to match

264

code: JavaScript code to execute

265

266

Returns:

267

Conditional execution script

268

"""

269

270

def run_js(js: str, id=None, **kwargs):

271

"""

272

Execute JavaScript with automatic ID generation.

273

274

Args:

275

js: JavaScript code to run

276

id: Element ID (auto-generated if None)

277

**kwargs: Additional script attributes

278

279

Returns:

280

Script element with executable JavaScript

281

"""

282

```

283

284

### HTMX JavaScript Integration

285

286

JavaScript utilities specifically designed for HTMX interactions.

287

288

```python { .api }

289

def HtmxOn(eventname: str, code: str):

290

"""

291

HTMX event handler script generator.

292

293

Creates JavaScript event handlers that work

294

seamlessly with HTMX requests and responses.

295

296

Args:

297

eventname: HTMX event name (e.g., 'htmx:afterSwap')

298

code: JavaScript code to execute on event

299

300

Returns:

301

Script element with HTMX event handler

302

"""

303

304

def clear(id: str):

305

"""

306

Clear element content by ID.

307

308

Generates JavaScript to clear element content,

309

compatible with HTMX workflows.

310

311

Args:

312

id: Element ID to clear

313

314

Returns:

315

JavaScript code for clearing element content

316

"""

317

```

318

319

### JavaScript Source Constants

320

321

Pre-defined JavaScript source URLs and code snippets.

322

323

```python { .api }

324

htmxsrc: str

325

"""HTMX JavaScript source URL."""

326

327

fhjsscr: str

328

"""FastHTML JavaScript source code."""

329

330

surrsrc: str

331

"""Surreal.js JavaScript source URL."""

332

333

scopesrc: str

334

"""Scope JavaScript source code."""

335

```

336

337

## Usage Examples

338

339

### Markdown Rendering

340

341

```python

342

from fasthtml.common import *

343

344

app, rt = fast_app()

345

346

@rt('/markdown')

347

def markdown_demo():

348

return Titled("Markdown Rendering",

349

Container(

350

H1("Markdown with JavaScript"),

351

352

# Markdown input area

353

Div(

354

H2("Write Markdown"),

355

Textarea(

356

id="markdown-input",

357

placeholder="# Hello World\n\nType your **markdown** here...",

358

rows="10",

359

style="width: 100%; font-family: monospace;"

360

),

361

Button(

362

"Render Markdown",

363

onclick="renderMarkdown()",

364

cls="primary"

365

)

366

),

367

368

# Rendered output

369

Div(

370

H2("Rendered Output"),

371

Div(id="markdown-output", style="border: 1px solid #ccc; padding: 1rem; min-height: 200px;")

372

),

373

374

# Include Markdown.js

375

MarkdownJS(),

376

377

# Custom JavaScript for rendering

378

Script("""

379

function renderMarkdown() {

380

const input = document.getElementById('markdown-input').value;

381

const output = document.getElementById('markdown-output');

382

383

// Using markdown-it library

384

const md = window.markdownit();

385

const rendered = md.render(input);

386

output.innerHTML = rendered;

387

}

388

389

// Auto-render on load if there's content

390

document.addEventListener('DOMContentLoaded', function() {

391

const input = document.getElementById('markdown-input');

392

if (input.value.trim()) {

393

renderMarkdown();

394

}

395

});

396

""")

397

)

398

)

399

400

@rt('/markdown-math')

401

def markdown_math_demo():

402

return Titled("Markdown with Math",

403

Container(

404

H1("Markdown with KaTeX Math"),

405

406

# Sample content with math

407

Div(id="math-content", """

408

# Mathematical Expressions

409

410

Inline math: $E = mc^2$

411

412

Block math:

413

$$

414

\\int_{-\\infty}^{\\infty} e^{-x^2} dx = \\sqrt{\\pi}

415

$$

416

417

More complex equation:

418

$$

419

\\frac{1}{\\sqrt{2\\pi\\sigma^2}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}

420

$$

421

"""),

422

423

# Include Markdown.js with KaTeX

424

KatexMarkdownJS(),

425

426

Script("""

427

document.addEventListener('DOMContentLoaded', function() {

428

const content = document.getElementById('math-content');

429

const md = window.markdownit({

430

html: true,

431

typographer: true

432

});

433

434

// Render markdown with math

435

const rendered = md.render(content.textContent);

436

content.innerHTML = rendered;

437

438

// Render KaTeX math

439

renderMathInElement(content, {

440

delimiters: [

441

{left: "$$", right: "$$", display: true},

442

{left: "$", right: "$", display: false}

443

]

444

});

445

});

446

""")

447

)

448

)

449

```

450

451

### Syntax Highlighting

452

453

```python

454

from fasthtml.common import *

455

456

app, rt = fast_app()

457

458

@rt('/syntax-highlighting')

459

def syntax_demo():

460

return Titled("Syntax Highlighting",

461

Container(

462

H1("Code Syntax Highlighting"),

463

464

# Python code example

465

Div(

466

H2("Python Code"),

467

Pre(Code("""

468

def fibonacci(n):

469

\"\"\"Generate Fibonacci sequence up to n terms.\"\"\"

470

if n <= 0:

471

return []

472

elif n == 1:

473

return [0]

474

elif n == 2:

475

return [0, 1]

476

477

sequence = [0, 1]

478

for i in range(2, n):

479

sequence.append(sequence[i-1] + sequence[i-2])

480

481

return sequence

482

483

# Generate first 10 Fibonacci numbers

484

result = fibonacci(10)

485

print(f"First 10 Fibonacci numbers: {result}")

486

""", cls="language-python"))

487

),

488

489

# JavaScript code example

490

Div(

491

H2("JavaScript Code"),

492

Pre(Code("""

493

class Calculator {

494

constructor() {

495

this.result = 0;

496

}

497

498

add(value) {

499

this.result += value;

500

return this;

501

}

502

503

multiply(value) {

504

this.result *= value;

505

return this;

506

}

507

508

getValue() {

509

return this.result;

510

}

511

}

512

513

// Usage example

514

const calc = new Calculator();

515

const result = calc.add(5).multiply(3).add(2).getValue();

516

console.log(`Result: ${result}`); // Result: 17

517

""", cls="language-javascript"))

518

),

519

520

# SQL code example

521

Div(

522

H2("SQL Code"),

523

Pre(Code("""

524

-- Create users table

525

CREATE TABLE users (

526

id SERIAL PRIMARY KEY,

527

username VARCHAR(50) UNIQUE NOT NULL,

528

email VARCHAR(100) UNIQUE NOT NULL,

529

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

530

);

531

532

-- Insert sample data

533

INSERT INTO users (username, email) VALUES

534

('john_doe', 'john@example.com'),

535

('jane_smith', 'jane@example.com');

536

537

-- Query with join

538

SELECT u.username, u.email, p.title

539

FROM users u

540

LEFT JOIN posts p ON u.id = p.user_id

541

WHERE u.created_at > '2024-01-01'

542

ORDER BY u.created_at DESC;

543

""", cls="language-sql"))

544

),

545

546

# Include Highlight.js

547

HighlightJS(),

548

549

# Initialize highlighting

550

Script("""

551

document.addEventListener('DOMContentLoaded', function() {

552

hljs.highlightAll();

553

});

554

""")

555

)

556

)

557

```

558

559

### Drag and Drop Functionality

560

561

```python

562

from fasthtml.common import *

563

564

app, rt = fast_app()

565

566

@rt('/drag-drop')

567

def sortable_demo():

568

return Titled("Drag and Drop",

569

Container(

570

H1("Sortable Lists"),

571

572

# Simple sortable list

573

Div(

574

H2("Task List"),

575

Ul(

576

Li("Complete project proposal", id="task-1", cls="sortable-item"),

577

Li("Review code changes", id="task-2", cls="sortable-item"),

578

Li("Update documentation", id="task-3", cls="sortable-item"),

579

Li("Run test suite", id="task-4", cls="sortable-item"),

580

Li("Deploy to staging", id="task-5", cls="sortable-item"),

581

id="task-list",

582

style="list-style: none; padding: 0;"

583

),

584

P("Drag and drop to reorder tasks.")

585

),

586

587

# Sortable grid

588

Div(

589

H2("Image Gallery"),

590

Div(

591

*[Div(

592

Img(src=f"https://picsum.photos/150/150?random={i}", alt=f"Image {i}"),

593

P(f"Image {i}", style="text-align: center; margin: 0.5rem 0;"),

594

cls="gallery-item",

595

style="border: 1px solid #ddd; padding: 0.5rem; margin: 0.5rem;"

596

) for i in range(1, 9)],

597

id="image-gallery",

598

style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem;"

599

),

600

P("Drag images to rearrange the gallery.")

601

),

602

603

# Include SortableJS

604

SortableJS(),

605

606

# Initialize sortable functionality

607

Script("""

608

document.addEventListener('DOMContentLoaded', function() {

609

// Make task list sortable

610

const taskList = document.getElementById('task-list');

611

new Sortable(taskList, {

612

animation: 150,

613

ghostClass: 'sortable-ghost',

614

onEnd: function(evt) {

615

console.log('Task moved from', evt.oldIndex, 'to', evt.newIndex);

616

// Here you could send the new order to the server

617

}

618

});

619

620

// Make image gallery sortable

621

const gallery = document.getElementById('image-gallery');

622

new Sortable(gallery, {

623

animation: 150,

624

ghostClass: 'sortable-ghost',

625

onEnd: function(evt) {

626

console.log('Image moved from', evt.oldIndex, 'to', evt.newIndex);

627

}

628

});

629

});

630

"""),

631

632

# CSS for sortable items

633

Style("""

634

.sortable-item {

635

padding: 0.75rem;

636

margin: 0.25rem 0;

637

background: #f8f9fa;

638

border: 1px solid #dee2e6;

639

border-radius: 0.25rem;

640

cursor: move;

641

transition: all 0.2s;

642

}

643

644

.sortable-item:hover {

645

background: #e9ecef;

646

transform: translateY(-1px);

647

box-shadow: 0 2px 4px rgba(0,0,0,0.1);

648

}

649

650

.sortable-ghost {

651

opacity: 0.4;

652

background: #007bff !important;

653

color: white;

654

}

655

656

.gallery-item {

657

cursor: move;

658

transition: transform 0.2s;

659

}

660

661

.gallery-item:hover {

662

transform: scale(1.05);

663

}

664

""")

665

)

666

)

667

```

668

669

### Interactive Diagrams

670

671

```python

672

from fasthtml.common import *

673

674

app, rt = fast_app()

675

676

@rt('/diagrams')

677

def diagram_demo():

678

return Titled("Interactive Diagrams",

679

Container(

680

H1("Mermaid.js Diagrams"),

681

682

# Flowchart

683

Div(

684

H2("Process Flowchart"),

685

Div("""

686

graph TD

687

A[Start] --> B{Is it working?}

688

B -->|Yes| C[Great!]

689

B -->|No| D[Debug]

690

D --> E[Fix Issues]

691

E --> B

692

C --> F[Deploy]

693

F --> G[End]

694

""", cls="mermaid")

695

),

696

697

# Sequence diagram

698

Div(

699

H2("API Sequence Diagram"),

700

Div("""

701

sequenceDiagram

702

participant Client

703

participant API

704

participant Database

705

706

Client->>API: POST /users

707

API->>Database: INSERT user

708

Database-->>API: User created

709

API-->>Client: 201 Created

710

711

Client->>API: GET /users/123

712

API->>Database: SELECT user

713

Database-->>API: User data

714

API-->>Client: 200 OK

715

""", cls="mermaid")

716

),

717

718

# Gantt chart

719

Div(

720

H2("Project Timeline"),

721

Div("""

722

gantt

723

title Project Development Timeline

724

dateFormat YYYY-MM-DD

725

section Planning

726

Requirements :req, 2024-01-01, 2024-01-15

727

Design :design, after req, 10d

728

section Development

729

Backend :backend, 2024-01-20, 20d

730

Frontend :frontend, after design, 25d

731

section Testing

732

Unit Tests :test1, after backend, 5d

733

Integration :test2, after frontend, 10d

734

section Deployment

735

Staging :staging, after test2, 3d

736

Production :prod, after staging, 2d

737

""", cls="mermaid")

738

),

739

740

# Include Mermaid.js

741

MermaidJS(),

742

743

# Initialize Mermaid

744

Script("""

745

document.addEventListener('DOMContentLoaded', function() {

746

mermaid.initialize({

747

startOnLoad: true,

748

theme: 'default',

749

flowchart: {

750

useMaxWidth: true,

751

htmlLabels: true

752

}

753

});

754

});

755

""")

756

)

757

)

758

```

759

760

### Client-Side Interactions with Surreal.js

761

762

```python

763

from fasthtml.common import *

764

765

app, rt = fast_app(surreal=True)

766

767

@rt('/surreal-demo')

768

def surreal_demo():

769

return Titled("Surreal.js Demo",

770

Container(

771

H1("Client-Side Interactions"),

772

773

# DOM manipulation examples

774

Div(

775

H2("DOM Manipulation"),

776

Button("Change Text", id="change-text-btn"),

777

Button("Add Item", id="add-item-btn"),

778

Button("Toggle Visibility", id="toggle-btn"),

779

P("This text will change", id="dynamic-text"),

780

Ul(id="dynamic-list"),

781

Div("This div will toggle", id="toggle-div", style="margin-top: 1rem; padding: 1rem; background: #f0f0f0;")

782

),

783

784

# Form interactions

785

Div(

786

H2("Form Interactions"),

787

Input(type="text", id="name-input", placeholder="Enter your name"),

788

Button("Greet", id="greet-btn"),

789

P(id="greeting-output")

790

),

791

792

# Surreal.js code

793

Surreal("""

794

// DOM manipulation examples

795

$("#change-text-btn").on("click", () => {

796

$("#dynamic-text").text("Text changed at " + new Date().toLocaleTimeString());

797

});

798

799

$("#add-item-btn").on("click", () => {

800

const itemCount = $("#dynamic-list li").length + 1;

801

$("#dynamic-list").append(`<li>Item ${itemCount}</li>`);

802

});

803

804

$("#toggle-btn").on("click", () => {

805

$("#toggle-div").toggle();

806

});

807

808

// Form interactions

809

$("#greet-btn").on("click", () => {

810

const name = $("#name-input").value;

811

if (name) {

812

$("#greeting-output").text(`Hello, ${name}! Nice to meet you.`);

813

} else {

814

$("#greeting-output").text("Please enter your name first.");

815

}

816

});

817

818

// Real-time input feedback

819

$("#name-input").on("input", (e) => {

820

const value = e.target.value;

821

if (value.length > 0) {

822

$("#greet-btn").removeAttribute("disabled");

823

} else {

824

$("#greet-btn").setAttribute("disabled", "true");

825

}

826

});

827

""")

828

)

829

)

830

```

831

832

### CDN Library Integration

833

834

```python

835

from fasthtml.common import *

836

837

app, rt = fast_app()

838

839

@rt('/cdn-libraries')

840

def cdn_demo():

841

return Titled("CDN Library Integration",

842

Container(

843

H1("External Library Integration"),

844

845

# Chart.js example

846

Div(

847

H2("Chart Visualization"),

848

Canvas(id="chart-canvas", width="400", height="200"),

849

Button("Update Chart", id="update-chart-btn")

850

),

851

852

# Lodash utility example

853

Div(

854

H2("Data Processing"),

855

Pre(id="data-output", style="background: #f8f9fa; padding: 1rem; border-radius: 0.25rem;"),

856

Button("Process Data", id="process-data-btn")

857

),

858

859

# Load Chart.js from CDN

860

jsd("chart.js", "3.9.1"),

861

862

# Load Lodash from CDN

863

jsd("lodash", "4.17.21"),

864

865

# Custom JavaScript using loaded libraries

866

Script("""

867

document.addEventListener('DOMContentLoaded', function() {

868

// Chart.js example

869

const ctx = document.getElementById('chart-canvas').getContext('2d');

870

let chart = new Chart(ctx, {

871

type: 'bar',

872

data: {

873

labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],

874

datasets: [{

875

label: 'Votes',

876

data: [12, 19, 3, 5, 2, 3],

877

backgroundColor: [

878

'rgba(255, 99, 132, 0.5)',

879

'rgba(54, 162, 235, 0.5)',

880

'rgba(255, 205, 86, 0.5)',

881

'rgba(75, 192, 192, 0.5)',

882

'rgba(153, 102, 255, 0.5)',

883

'rgba(255, 159, 64, 0.5)'

884

]

885

}]

886

},

887

options: {

888

responsive: true,

889

scales: {

890

y: {

891

beginAtZero: true

892

}

893

}

894

}

895

});

896

897

// Update chart with random data

898

document.getElementById('update-chart-btn').addEventListener('click', function() {

899

chart.data.datasets[0].data = chart.data.datasets[0].data.map(() =>

900

Math.floor(Math.random() * 20) + 1

901

);

902

chart.update();

903

});

904

905

// Lodash example

906

document.getElementById('process-data-btn').addEventListener('click', function() {

907

const rawData = [

908

{ name: 'John', age: 30, city: 'New York' },

909

{ name: 'Jane', age: 25, city: 'San Francisco' },

910

{ name: 'Bob', age: 35, city: 'New York' },

911

{ name: 'Alice', age: 28, city: 'San Francisco' },

912

{ name: 'Charlie', age: 32, city: 'Chicago' }

913

];

914

915

// Use Lodash to process data

916

const groupedByCity = _.groupBy(rawData, 'city');

917

const avgAgeByCity = _.mapValues(groupedByCity, (people) =>

918

_.round(_.meanBy(people, 'age'), 1)

919

);

920

const sortedCities = _.sortBy(Object.keys(avgAgeByCity));

921

922

const result = {

923

'Total People': rawData.length,

924

'Cities': sortedCities,

925

'Average Age by City': avgAgeByCity,

926

'Oldest Person': _.maxBy(rawData, 'age'),

927

'Youngest Person': _.minBy(rawData, 'age')

928

};

929

930

document.getElementById('data-output').textContent =

931

JSON.stringify(result, null, 2);

932

});

933

});

934

""")

935

)

936

)

937

```