docs/tutorial/fundamentals.md
[!TLDR]
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.
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>
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>
[!NOTE] The Reference Docs explain more about Attributes including how they support
...spreadsandmethods().
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>
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.
/* tags/card.marko */
<div>
<h3>Alice</h3>
<p>Designer</p>
<p>Joined 2023</p>
</div>
This <card> component can now be used anywhere in the page:
<h1>Our Team</h1>
<card/>
<card/>
<card/>
<!---->[!NOTE] Components in the
tags/directory are automatically discovered. No need toimportthem.
[!TIP] We can also write multiple "components" in a single file using the
<define>tag.
Attributes on custom components are available through a special object called input.
/* card.marko */
export interface Input {
name: string;
role: string;
year: number;
}
<div>
<h3>${input.name}</h3>
<p>${input.role}</p>
<p>Joined ${input.year}</p>
</div>
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/>
[!NOTE] Also check out attribute tags which we can use to pass named content to a component
Marko provides many helpful Core Tags. For example, we can use <if> and <else> to show or hide content based on conditions.
/* tags/product.marko */
<div>
<h3>${input.name}</h3>
<p>$${input.price}</p>
<if=input.stock>
<button>Add to Cart</button>
</if>
<else>
<button disabled>Out of Stock</button>
</else>
</div>
Now we can show different states based on the product data:
<product name="T-Shirt" price=25 stock=10/>
<product name="Hoodie" price=45 stock=0/>
<product name="Hat" price=15 stock=5/>
And we can use the <for> tag to display repeated content
<for|product| of=productsList>
<product name=product.name price=product.price stock=product.stock/>
</for>