Quick start

Installation

Start with a blank Go project and install magic with the following command.
go get github.com/Instantan/magic

Web server

In the main.go file, create a simple web server. The only magic specific thing here is the magic.CompressedComponentHTTPHandler(index) wich takes a component and returns a http.Handler. You can use any std-library compatible router/server/mux you want.
Note that the following code wont compile on it's own.
main.go
package main import ( "log" "net/http" "github.com/Instantan/magic" ) func main() { magic.HotReload() // include this line if you want to hot reload your application on save mux := http.NewServeMux() mux.Handle("/", magic.CompressedComponentHTTPHandler(index)) log.Print("Listening to http://localhost:8070") if err := http.ListenAndServe(":8070", mux); err != nil { log.Fatal(err) } }

First view

Create a new file index.go. In that file you will create the first view. Views in magic are simple http templates. The templates are like mustache templates logicless. It's recommended that the views are created on the top level, because the view creation is somewhat expensive.
The indexView contains a basic HTML page. The body includes a tag with the name body. In this placeholder you will render the to displaying data.
Note that the following code wont compile on it's own.
index.go
package main import ( "github.com/Instantan/magic" ) var indexView = magic.View(` <!DOCTYPE html> <html> <head> <title>Learn</title> </head> <body> {{ body }} </body> </html> `)

Simple component

To render a view you first need to create a component. The first argument of the component takes always a magic.Socket. The second argument is a generic one. It can take any type you want and is used to pass down data to the component. This example uses the type magic.Empty wich is just a empty struct.
Add the component just under the view you just created. In that component use the magic.Assign function to assign the value "Hello World" to the Socket.
The index.go will looks afterwards like the following snippet.
Now the project is runnable (go run .) and shows under the url http://localhost:8070 the expected site.
index.go
package main import ( "github.com/Instantan/magic" ) var indexView = magic.View(` <!DOCTYPE html> <html> <head> <title>Learn</title> </head> <body> {{ body }} </body> </html> `) var index = magic.Component(func(s magic.Socket, _ magic.Empty) magic.AppliedView { magic.Assign(s, "body", "Hello World") return indexView(s) })

Make it live

So far there is nothing much magical about this. You can statically render websites based on composeable components, but thats it.

This is where the magic starts. Magic injects a 12kb (4.6kb gzipped) small JavaScript script into the header of each website. This script turns every site into a soft realtime updateable web app. To demonstrate this we add the following code into our index component. So that our index.go file looks like the following snippet.

This snippet checks if the socket is a live socket. Then it starts a ticker. Every seconds we call magic.Assign and assign the value of the current ticker time to the tag "body". Then call the s.HandleEvent method and stop the timer when the unmount event is received.

If you run the project (go run .) and visit the site under http://localhost:8070 you will see that the Hello World on the screen will turn into the current Date and Time that updates every second.
index.go
package main import ( "github.com/Instantan/magic" ) var indexView = magic.View(` <!DOCTYPE html> <html> <head> <title>Learn</title> </head> <body> {{ body }} </body> </html> `) var index = magic.Component(func(s magic.Socket, _ magic.Empty) magic.AppliedView { magic.Assign(s, "body", "Hello World") if s.Live() { t := time.NewTicker(time.Second) go func() { for r := range t.C { magic.Assign(s, "body", r.String()) } }() s.HandleEvent(func(e string, d magic.EventData) { switch e { case magic.UnmountEvent: t.Stop() } }) } return indexView(s) })

You can find the full example under github.com/Instantan/magic-quickstart-example.
Advanced

Events

Send events like onclick from the client to the server and handle it in your component.

Static nodes

Sometimes you dont want to live render some nodes. For example when you manipulate divs with JavaScript. If thats the case you can use the HTML Attribute magic:static="a". Only when the value equals the live rendered value the node gets ignored.

JavaScript

-

Hooks

-

Deferred assigns

-

Deferred components

-

Temporal data patches

-

Handlers

-