Getting Started

Create an Application

Getting Started

Create an Application

The application instance

Every Spec application starts by creating a new application instance with the createApp function:

JS

import { createApp } from 'spec'

const app = createApp({
  /* root component options */
})

The Root Component

The object we are passing into createApp is in fact a component. Every app requires a "root component" that can contain other components as its children.

Terminal

import { createApp } from 'spec'
// import the root component App from a single-file component.
import App './Apps.spec'

const app = createApp(App)

While many examples in this guide only need a single component, most real applications are organized into a tree of nested, reusable components. For example, a Todo application's component tree might look like this:

Terminal

App (root component)
├─ TodoList
│  └─ TodoItem
│     ├─ TodoDeleteButton
│     └─ TodoEditButton
└─ TodoFooter
   ├─ TodoClearButton
   └─ TodoStatistics

Sections of the guide, we will discuss how to define and compose multiple components together. Before that, we will focus on what happens inside a single component.

Mounting the App

An application instance won't render anything until its .mount() method is called. It expects a "container" argument, which can either be an actual DOM element or a selector string:

Terminal

// SearchBar is a Client Component
import SearchBar from './searchbar'
// Logo is a Server Component
import Logo from './logo'
 
// Layout is a Server Component by default
export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <nav>
        <Logo />
        <SearchBar />
      </nav>
      <main>{children}</main>
    </>
  )
}

Composing Client and Server Components

Server and Client Components can be combined in the same component tree. Behind the scenes, React handles rendering as follows:

Nesting Server Components inside Client Components

Given the rendering flow outlined above, there is a restriction around importing a Server Component into a Client Component, as this approach would require an additional server round trip.

Unsupported Pattern: Importing Server Components into Client Components The following pattern is not supported. You cannot import a Server Component into a Client Component:

package.json

'use client'
 
// This pattern will **not** work!
// You cannot import a Server Component into a Client Component.
import ExampleServerComponent from './example-server-component'
 
export default function ExampleClientComponent({
  children,
}: {
  children: React.ReactNode
}) {
  const [count, setCount] = useState(0)
 
  return (
    <>
      <button onClick={() => setCount(count + 1)}>{count}</button>
 
      <ExampleServerComponent />
    </>
  )
}

What do you need to do?

Server Component

Client Component

Fetch data.

Fetch data.

Access backend resources

None

Add interactivity and event

React Essentials

Building Your Application

TypeScript