Marko Fundamentals
Marko builds on top of HTML, enabling components and JavaScript-based interpolation
Marko is designed to feel familiar if you know HTML, while making it easy to build dynamic, interactive websites. Let's walk through the core concepts.
Templates are HTML
Nearly any valid HTML is also valid Marko code. We can start with regular HTML and gradually add features as needed.
<h1>My Blog</h1>
<nav>
<a href="/about">
About
</a>
<a href="/contact">
Contact
</a>
</nav>
h1 -- My Blog
nav
a href="/about" -- About
a href="/contact" -- Contact
Attributes are JS
Almost all valid JavaScript expressions can be written as attribute values.
<a href=`/user/${user.id}`>
My Profile
</a>
<a href=getRandomPage()>
Discover Something New
</a>
a href=`/user/${user.id}` -- My Profile
a href=getRandomPage() -- Discover Something New
The Reference Docs explain more about Attributes including how they support ...spreads
and methods()
.
Dynamic Content
Tag content in Marko is similar to template literals in JavaScript, so dynamic text can be added with interpolated ${expressions}
<p>Today is ${new Date().toDateString()}</p>
<p>Random number: ${Math.floor(Math.random() * 100)}</p>
p -- Today is ${new Date().toDateString()}
p -- Random number: ${Math.floor(Math.random() * 100)}
Components
To reuse code, we can move it into a separate file. Each .marko
file is a component that can be used like an HTML tag.
<div>
<h3>Alice</h3>
<p>Designer</p>
<p>Joined 2023</p>
</div>
div
h3 -- Alice
p -- Designer
p -- Joined 2023
This <card>
component can now be used anywhere in the page:
<h1>Our Team</h1>
<card/>
<card/>
<card/>
h1 -- Our Team
card
card
card
Components in the tags/
directory are automatically discovered. No need to import
them.
We can also write multiple "components" in a single file using the <define>
tag.
Passing Data to Components
Attributes on custom components are available through a special object called input
.
<div>
<h3>${input.name}</h3>
<p>${input.role}</p>
<p>Joined ${input.year}</p>
</div>
export interface Input {
name: string;
role: string;
year: number;
}
<div>
<h3>${input.name}</h3>
<p>${input.role}</p>
<p>Joined ${input.year}</p>
</div>
div
h3 -- ${input.name}
p -- ${input.role}
p -- Joined ${input.year}
export interface Input {
name: string;
role: string;
year: number;
}
div
h3 -- ${input.name}
p -- ${input.role}
p -- Joined ${input.year}
Now we can pass different data to each instance of card
:
<h1>Our Team</h1>
<card name="Alice" role="Designer" year=2023/>
<card name="Bob" role="Developer" year=2024/>
<card name="Charlie" role="Product Manager" year=2022/>
h1 -- Our Team
card name="Alice" role="Designer" year=2023
card name="Bob" role="Developer" year=2024
card name="Charlie" role="Product Manager" year=2022
Also check out attribute tags which we can use to pass named content to a component
Next Steps
Contributors
Helpful? You can thank these awesome people! You can also edit this doc if you see any issues or want to improve it.