SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS [email protected], !...
Transcript of SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS [email protected], !...
![Page 1: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/1.jpg)
A D V E N T U R E S I N
S E O A N D S I N G L E - P A G E W E B A P P S
M AT T I @ V A A D I N . C O M , ! @ M AT T I TA H V O N E N , G I T H U B . C O M / M S TA H V
5
S T O R Y A N D P H I L O S O P H Y
Software is eating the world and what most of us see of it is the user interface. The user
interface has become the key component of how the users experience the business
behind it. Competition is lost or won due to user experience. Simplicity is king and the
users get frustrated by anything ugly, slow or not working on the device they happen to
use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight.
Together we want to build a user interface that puts a smile on the user’s face.
Vaadin is the technology that empowers developers to build the best web-apps for
business purposes. Our priority over everything else is developer productivity because
we believe that by simplifying the developer experience and saving the developer’s
time, they are best able to focus on building great user interfaces.
Our brand is what we want everyone to think about us. When everyone - both us and
the people around us - have a consistent understanding of what Vaadin is and what we
stand for, it enables that image to spread and amplify. This book defines what we want
that image to be. It defines what the Vaadin brand is.
I hope that You are as excited and proud of living and breathing the Vaadin brand as
I am. You are the one who is shaping what everyone thinks about Vaadin - using this
brand as a tool and a guideline every day.
Let’s fight for simplicity for both the users and the developers!
Joonas Lehtinen
Founder & CEO
Vaadin
I N T R O D U C T I O N
![Page 2: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/2.jpg)
![Page 3: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/3.jpg)
Why this topic?
Over 10 years at Vaadin with SPAs
Over 20 years hacking web
Nicolas Fränkel
![Page 4: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/4.jpg)
things you'll learn
1. What are SPAs and why they are problematic with search engines?
2. You learn to consider if SPAs is really the best fit for your requirements. *)
3. Traditional and modern ways to make your SPA cope with search engines
4. SPAs can be search engine compatible!
*) I hope I don’t get fired questioning SPAs 😜
![Page 5: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/5.jpg)
SEO?
• Lot of things affect how well your page is found, too wide subject for conference presentation
• Cheating or helping search engines and users?
• In this session:
• On-Page SEO (in SPAs)
• SoMe social media integration (related)
![Page 6: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/6.jpg)
do you need SEO?
• Not necessarily!
• Web app vs web site
• Often quite black and white
• 71.3% of vaadin.com visitors come via search engines!
![Page 7: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/7.jpg)
S I N G L E - P A G E W E B A P P S ?
![Page 8: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/8.jpg)
A single-page application (SPA)
• No page reloads, “full AJAX” web apps
• JavaScript powered client side “rendering”
• New data (or views) loaded with XHR/JSONP/Websocket
• Faster interaction -> desktop like UX
![Page 9: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/9.jpg)
demo.vaadin.com/dashboard
![Page 10: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/10.jpg)
MyController.java my-view.template.html
my-view.css
my-view.js
@RestController @RequestMapping("/analytics") public class AnalyticsController {
@Autowired PatientsRepository patientsRepository;
@RequestMapping(path = "/age", method = RequestMethod.GET) public Response getByAge() { ... }
@RequestMapping(path = "/length", method = RequestMethod.GET) public Response getByLength() { ... } ... ...
<nav> <a href="/analytics/age" routerLinkActive="active">Age</a> <a href="/analytics/doctor" routerLinkActive="active">Doctor</a> <a href="/analytics/gender" routerLinkActive="active">Gender</a> </nav> ...
nav { justify-content: center; text-transform: uppercase; margin-bottom: 50px; } ...
getAnalytics(grouping: string = 'age') { return this.http .get(`${this.config.API_URL}/analytics/${grouping}`) .map(res=>res.json()); } ...
![Page 11: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/11.jpg)
F F SF I G H T F O R S I M P L I C I T Y
![Page 12: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/12.jpg)
new TextField(); new Button("Click me");
![Page 13: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/13.jpg)
new HorizontalLayout( new TextField(), new Button("Click me") );
![Page 14: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/14.jpg)
new VerticalLayout( new TextField(), new Button("Click me") );
![Page 15: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/15.jpg)
layout = new VerticalLayout(); textField = new TextField(); button = new Button("Click Me");
button.addClickListener(click -> layout.addComponent( new Label(textField.getValue()) ));
![Page 16: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/16.jpg)
TextField name = new TextField(); Button button = new Button("Greet"); layout.addComponents(name, button);
button.addClickListener(click -> { Notification.show("Hi, " + name.getValue()); });
![Page 17: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/17.jpg)
Initial HTML CSS JavaScript
(provided by the Framework)
~300k
![Page 18: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/18.jpg)
![Page 19: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/19.jpg)
{name: {value: 'Marcus'}, button: {event: 'clicked'}}
261 bytes
![Page 20: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/20.jpg)
TextField name = new TextField(); Button button = new Button("Greet"); layout.addComponents(name, button);
button.addClickListener(click -> { Notification.show("Hi, " + name.getValue()); });
![Page 21: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/21.jpg)
{name: {value: 'Marcus'}, button: {event: 'clicked'}}
261 bytes
{new: [ {notification: 'Hi, Marcus'} ]}
267 bytes
![Page 22: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/22.jpg)
save = new Button("Save", e -> { Notification.show(person.toString()); });
private TextField firstName; private TextField lastName;
person = new Person();
binder = new Binder<>( Person.class);
binder.bindInstanceFields(this);
![Page 23: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/23.jpg)
@Autowired private PersonService service;
Grid<Person> grid = new Grid<>();
// If you want custom columns grid.addColumn("First name", Person::getFirstName); grid.addColumn("Last name", Person::getLastName); grid.addColumn("Email", Person::getEmail);
grid.setItems(service.getPeople());
![Page 24: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/24.jpg)
@Autowired private PersonService service;
Grid<Person> grid = new Grid<>();
grid.addColumn("First name", Person::getFirstName); grid.addColumn("Last name", Person::getLastName); grid.addColumn("Email", Person::getEmail);
grid.setDataSource( new BackEndDataSource<>( q -> service.getPeople( q.getOffset(), q.getLimit()) .stream(), q -> service.count()));
![Page 25: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/25.jpg)
nav = new Navigator(this, navOutlet); nav.addView("", new DemoView("Hello, I'm view 1")); nav.addView("view2", new DemoView("Hello, I'm view 2"));
navBar = new HorizontalLayout(); navBar.addComponent( new Button("view1", click -> nav.navigateTo(""))); navBar.addComponent( new Button("view2", click -> nav.navigateTo("view2")));
CssLayout navOutlet = new CssLayout(); addComponents(navBar, navOutlet);
![Page 26: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/26.jpg)
$v-background-color: hsl(210, 0%, 100%);
![Page 27: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/27.jpg)
$v-background-color: hsl(210, 0%, 33%);
![Page 28: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/28.jpg)
$v-background-color: hsl(210, 0%, 100%); $v-border: 2px solid v-shade; $v-border-radius: 0; $v-bevel: false; $v-gradient: false; $v-shadow: false;
![Page 29: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/29.jpg)
SPA challenges
• Initial load time
• Multiple languages • Except in Vaadin’s approach
• Client-Server programming model • Except in Vaadin’s approach
• Back button support
• Deep linking
• Analytics
• Search engine optimisation
![Page 30: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/30.jpg)
SPA is not always the best solution!
• Site vs app
• Public vs private
• Sweet spot is private web app
• Consider “hybrid solutions”
App
Public Private
Site
![Page 31: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/31.jpg)
![Page 32: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/32.jpg)
![Page 33: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/33.jpg)
![Page 34: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/34.jpg)
![Page 35: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/35.jpg)
S P A ⚡ S E O
W H Y ?
![Page 36: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/36.jpg)
SPA ⚡ SEO
• Crawling + JavaScript
• Deep linking
• DOM in SPAs
![Page 37: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/37.jpg)
Crawling + JavaScript rendering
• Traditionally no JS support at all in bot
• Bots are getting better, e.g. content in Vaadin apps today:
• Google ✅
• Bing/Yahoo ✅
• Yandex 🚫
• Related : most social media integrations 🚫
![Page 38: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/38.jpg)
Deep linking
• Happens automatically in traditional web sites
• SPAs have no real page changes, no natural URLs
• Traditionally hacked with URI fragments (with hack² for SEO)
• HTML5 History API solves this
• IE 11+ & other modern browsers
![Page 39: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/39.jpg)
DOM in SPAs
• Components libraries often used in SPAs don’t necessarily use tag names relevant for bots (A, H1/H2…, TITLE, META tags)
• Navigating to another view might not happen with a link click, but with other element click, scrolling, gesture…
• Some content/links not always visible
![Page 40: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/40.jpg)
S P A & S E O
H O W ?
![Page 41: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/41.jpg)
SPA SEO techniques• Generic SEO techniques apply,
• Helping bots to crawl your site: • deep linking
• “hashbang” • History API
• Sitemaps • Content:
• Providing extra data for bots • <noscript>,<title> <meta> tags • serving custom non-SPA content for bots
• Pre-rendering
![Page 42: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/42.jpg)
# ! H A S H B A N G !
![Page 43: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/43.jpg)
Curiosity
#1 search engine company is probably the #1 SPA advocate.
![Page 44: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/44.jpg)
Hashbang technique1. special syntax of hash part of url means SE
should consider it as a “page”
2. Special hacks in browser (with iframes) to add entries to browser’s history (back button support)
3. special rules to convert hash into query parameter
4. special rules for the server side to render the same content for SE
![Page 45: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/45.jpg)
Server will never get the part starting from #
![Page 46: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/46.jpg)
![Page 47: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/47.jpg)
#! ⬌ ?_escaped_fragment_=
1. Bot detects #! urls as logical pages
2. Bot converts #! into special query parameter ?_escaped_fragment_=
3. Server returns a “pre-rendered” version for _escaped_fragement_ parameters
4. Search engine displays hashbang URLs
![Page 48: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/48.jpg)
Escaped fragment rendering:
![Page 49: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/49.jpg)
Hashbang technique• Kind of solves the SPAs SEO incompatibility
• Heavy to implement
• Invented by Google in 2009
• Deprecated by Google in 2015 (but still functional)
• GoogleBot (and some other crawlers) understand JS and actually render the page
• HTML5 History API and normal URLs!
![Page 50: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/50.jpg)
H T M L 5 H I S T O R Y A P I
![Page 51: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/51.jpg)
History API
• JS API to access browsers history (with certain limitations of course)
• history.back(), history.forward()
• supports adding new entries and listening to changes
• browser support since IE 10
![Page 52: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/52.jpg)
History API: pushState method
• Adds new entry to history
• parameters:
• state object
• title
• URL
![Page 53: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/53.jpg)
History API: replaceState method
• Modifies the current entry in history
• otherwise like pushState
![Page 54: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/54.jpg)
History API: PopState event
• Technically in window: window.onpopstate
• catch back/forward button click
• Naturally can be used to track just “in-page” navigation
![Page 55: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/55.jpg)
• Much cleaner solution than hashbang style
• You should use it today, unless really old browsers needs to be supported
• Together with possible JS support in bots, no server side hacks or pre-rendering needed
History API for SPA deep linking
![Page 56: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/56.jpg)
• Vaadin Framework 7: History add-on
• Low level support
• Navigator support: automatic modern SPA deep linking
• Will be supported by default in Vaadin 8
• Code examples…
History API: usage example
![Page 57: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/57.jpg)
H O W A B O U T M E TA TA G S ? A K A
W E S T I L L N E E D T H E S E R V E R - S I D E
Not just with Vaadin Framework :-)
![Page 58: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/58.jpg)
Meta tags?• Provides extra details for crawlers and other
bots
![Page 59: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/59.jpg)
• GoogleBot at least sometimes seems to pick up dynamically generated meta tags
• No-go with social media bots like Twitter and Google
• For perfect SEO, you’ll still need the server side.
Meta tags and bots
![Page 60: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/60.jpg)
• The code…
Meta tags example
![Page 61: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/61.jpg)
S P A S E O : T I P S A N D T R I C K S
![Page 62: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/62.jpg)
• If you want to see what a certain page looks like for bots, paste the URL directly to browser
• All relevant state for a logical page must be in URL for the server
Tip 1: Think like the bot
![Page 63: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/63.jpg)
• SPAs often contain dynamic content
• Menus
• Lazy loaded content
• Bots most probably never see dynamically loaded content!
• SPAs don’t necessarily use A elements for navigation
Tip 2: Ensure pages are referred
![Page 64: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/64.jpg)
• Standard xml files that describe your site content
• Submitted to search engines manually or preferably with a hint in robots.txt file
• Easiest way to ensure your whole SPA is indexed
Tip 3: Sitemaps
![Page 65: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/65.jpg)
• Not all search engine bots support JavaScript either, you’ll get at least something relevant for the index
• For most social media meta tags, only server side generated tags are valid (open graph, twitter etc)
Tip 4: Server generated meta tags
![Page 66: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/66.jpg)
• Heavy to implement, consider if you aim for best possible SEO
• Strategies:
• Manually with server side code, user agent detection or hash bang urls
• “Shadow URL” with redirect to SPA
• PhantomJS pre-rendering, prerender.io
• https://github.com/greengerong/prerender-java
Tip 5: Server side pre-rendering
![Page 67: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/67.jpg)
T H A N K Y O U5
S T O R Y A N D P H I L O S O P H Y
Software is eating the world and what most of us see of it is the user interface. The user
interface has become the key component of how the users experience the business
behind it. Competition is lost or won due to user experience. Simplicity is king and the
users get frustrated by anything ugly, slow or not working on the device they happen to
use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight.
Together we want to build a user interface that puts a smile on the user’s face.
Vaadin is the technology that empowers developers to build the best web-apps for
business purposes. Our priority over everything else is developer productivity because
we believe that by simplifying the developer experience and saving the developer’s
time, they are best able to focus on building great user interfaces.
Our brand is what we want everyone to think about us. When everyone - both us and
the people around us - have a consistent understanding of what Vaadin is and what we
stand for, it enables that image to spread and amplify. This book defines what we want
that image to be. It defines what the Vaadin brand is.
I hope that You are as excited and proud of living and breathing the Vaadin brand as
I am. You are the one who is shaping what everyone thinks about Vaadin - using this
brand as a tool and a guideline every day.
Let’s fight for simplicity for both the users and the developers!
Joonas Lehtinen
Founder & CEO
Vaadin
I N T R O D U C T I O N
M AT T I @ V A A D I N . C O M , ! @ M AT T I TA H V O N E N , G I T H U B . C O M / M S TA H V
![Page 68: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/68.jpg)
40% of Fortune 100 companies use Vaadin
150k+ active developers
#2 Java Web Frameworkaccording to Open HUB stats
Apache 2.0
![Page 69: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/69.jpg)
things you'll learn
1. What it takes to build a modern web app
2. The building blocks of Vaadin
3. How to build a full stack app in 30 minutes
![Page 70: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/70.jpg)
M O D E R N W E B A P P S
![Page 71: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/71.jpg)
demo.vaadin.com/dashboard
![Page 72: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/72.jpg)
MyController.java my-view.template.html
my-view.css
my-view.js
@RestController @RequestMapping("/analytics") public class AnalyticsController {
@Autowired PatientsRepository patientsRepository;
@RequestMapping(path = "/age", method = RequestMethod.GET) public Response getByAge() { ... }
@RequestMapping(path = "/length", method = RequestMethod.GET) public Response getByLength() { ... } ... ...
<nav> <a href="/analytics/age" routerLinkActive="active">Age</a> <a href="/analytics/doctor" routerLinkActive="active">Doctor</a> <a href="/analytics/gender" routerLinkActive="active">Gender</a> </nav> ...
nav { justify-content: center; text-transform: uppercase; margin-bottom: 50px; } ...
getAnalytics(grouping: string = 'age') { return this.http .get(`${this.config.API_URL}/analytics/${grouping}`) .map(res=>res.json()); }
![Page 73: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/73.jpg)
F F SF I G H T F O R S I M P L I C I T Y
![Page 74: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/74.jpg)
new TextField(); new Button("Click me");
![Page 75: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/75.jpg)
new HorizontalLayout( new TextField(), new Button("Click me") );
![Page 76: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/76.jpg)
new VerticalLayout( new TextField(), new Button("Click me") );
![Page 77: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/77.jpg)
layout = new VerticalLayout(); textField = new TextField(); button = new Button("Click Me");
button.addClickListener(click -> layout.addComponent( new Label(textField.getValue()) ));
![Page 78: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/78.jpg)
save = new Button("Save", e -> { // try-catch binder.writeBean(person);
Notification.show( person.toString()); });
private TextField firstName; private TextField lastName;
person = new Person();
binder = new BeanBinder<>( Person.class);
binder.bindInstanceFields(this);
![Page 79: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/79.jpg)
@Autowired private PersonService service;
Grid<Person> grid = new Grid<>();
grid.addColumn("First name", Person::getFirstName); grid.addColumn("Last name", Person::getLastName); grid.addColumn("Email", Person::getEmail);
grid.setItems(service.getPeople());
![Page 80: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/80.jpg)
@Autowired private PersonService service;
Grid<Person> grid = new Grid<>();
grid.addColumn("First name", Person::getFirstName); grid.addColumn("Last name", Person::getLastName); grid.addColumn("Email", Person::getEmail);
grid.setDataSource( new BackEndDataSource<>( q -> service.getPeople( q.getOffset(), q.getLimit()) .stream(), q -> service.count()));
![Page 81: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/81.jpg)
nav = new Navigator(this, navOutlet); nav.addView("", new DemoView("Hello, I'm view 1")); nav.addView("view2", new DemoView("Hello, I'm view 2"));
navBar = new HorizontalLayout(); navBar.addComponent( new Button("view1", click -> nav.navigateTo(""))); navBar.addComponent( new Button("view2", click -> nav.navigateTo("view2")));
CssLayout navOutlet = new CssLayout(); addComponents(navBar, navOutlet);
![Page 82: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/82.jpg)
$v-background-color: hsl(210, 0%, 100%);
![Page 83: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/83.jpg)
$v-background-color: hsl(210, 0%, 33%);
![Page 84: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/84.jpg)
$v-background-color: hsl(210, 0%, 100%); $v-border: 2px solid v-shade; $v-border-radius: 0; $v-bevel: false; $v-gradient: false; $v-shadow: false;
![Page 85: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/85.jpg)
![Page 86: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/86.jpg)
![Page 87: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/87.jpg)
[insert code here]
![Page 88: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/88.jpg)
" github.com/vaadin-marcus/spring-boot-todo
![Page 89: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/89.jpg)
TextField name = new TextField(); Button button = new Button("Greet"); layout.addComponents(name, button);
button.addClickListener(click -> { Notification.show("Hi, " + name.getValue()); });
![Page 90: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/90.jpg)
Initial HTML CSS JavaScript
~300k
![Page 91: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/91.jpg)
![Page 92: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/92.jpg)
{name: {value: 'Marcus'}, button: {event: 'clicked'}}
261 bytes
![Page 93: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/93.jpg)
TextField name = new TextField(); Button button = new Button("Greet"); layout.addComponents(name, button);
button.addClickListener(click -> { Notification.show("Hi, " + name.getValue()); });
![Page 94: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/94.jpg)
{name: {value: 'Marcus'}, button: {event: 'clicked'}}
261 bytes
{new: [ {notification: 'Hi, Marcus'} ]}
267 bytes
![Page 95: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/95.jpg)
![Page 96: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/96.jpg)
.v-ui[width-range~="0-800px"]{ /* Styles for small devices */ } .v-ui[width-range~="801px-"]{ /* Styles for large devices */ }
getPage().addBrowserWindowResizeListener( newSize -> { if (newSize.getWidth() > LARGE_DEVICE_WIDTH){ setupLargeLayout(); } else { setupSmallLayout(); } });
![Page 97: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/97.jpg)
W E B S O C K E T S
public class VaadinUI extends UI { ...
}
@Push
ui.access(() -> Notification.show("Alert!"));
![Page 98: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/98.jpg)
�����
![Page 99: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/99.jpg)
S T R O N G S E C U R I T Y#
![Page 100: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/100.jpg)
T H E J V M♥
![Page 101: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/101.jpg)
E X T E N D A B L E%
![Page 102: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/102.jpg)
![Page 103: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/103.jpg)
![Page 104: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/104.jpg)
![Page 105: SINGLE-PAGE WEB APPS · ADVENTURES IN SEO AND SINGLE-PAGE WEB APPS MATTI@VAADIN.COM, ! @MATTITAHVONEN, GITHUB.COM/MSTAHV 5 STORY AND PHILOSOPHY Software is eating the world and what](https://reader033.fdocuments.net/reader033/viewer/2022050406/5f83a0722030541511188179/html5/thumbnails/105.jpg)
We'd be happy to help you.