Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 7 additions & 24 deletions home/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,34 +363,17 @@ func indexBody() string {
</style>`
}

// topRight is the corner: the way in, and nothing else.
//
// One link. It was Sign up and Log in, on the argument that a stranger here is
// deciding whether to join and somebody returning already decided — which is
// true and put two controls in a corner whose whole job is to be the one thing
// you can do from here. The login page offers signing up on it, so nothing is
// lost but a fork in front of somebody who has not asked for one.
//
// Nothing else has ever earned this slot. Install app stood here for a while
// and appeared on only some browsers, saying nothing about what state you are
// in or what to do about it, which is the corner's entire purpose.
// topRight is the landing's corner: the way to have an account, and the way
// back to one.
//
// The same pair the app shell draws — see app.headCorner, which carries the
// reasoning and the invite-only exception. Written out here rather than called,
// because this page has its own shell and its own stylesheet: the corner in
// mu.css is #head-out and this one is .login-link, and the markup differs by
// the wrapper each of them needs.
// topRight is the landing's corner: the public catalogue and the way in.
//
// Two links, for the two audiences arriving here. Tools takes an agent builder
// to the machine-facing catalogue; Log in takes a returning person home. Sign
// up remains one step behind Log in, on the login page, rather than making
// three competing actions in this small corner.
//
// No redirect on the way in. The landing is the one page where signing in
// should move you somewhere else, and it already does.
func topRight() string {
signup := ""
if !auth.InviteOnly() {
signup = `<a class="primary" href="/signup">Sign up</a>`
}
return signup + `<a href="/login">Log in</a>`
return `<a href="/tools">Tools</a><a href="/login">Log in</a>`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep Sign up visible on the landing page

For a first-time visitor arriving at /, this removes the only explicit registration action and requires them to choose “Log in” before learning they can create an account. This is a known acquisition regression: the rationale for headCorner in internal/app/app.go lines 1473–1480 records that the same one-hop design caused the instance to stop receiving signups because new visitors do not select Log in. Keep a visible Sign up action on the public front door while adding Tools rather than reintroducing that behavior.

Useful? React with 👍 / 👎.

}

// today is what you are given for arriving, before you ask anything.
Expand Down
34 changes: 15 additions & 19 deletions home/landing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,27 @@ func TestTheWordmarkSaysWhatItIs(t *testing.T) {
}
}

// The corner offers an account, not only a way back to one.
// The corner offers the public tool catalogue and one way into an account.
//
// The landing's corner was cut to Log in for the same reason the shell's was —
// see app.headCorner — and this is the page where it cost the most: everybody
// standing here is a stranger, because signing in redirects to /home.
func TestTheLandingOffersAWayToJoin(t *testing.T) {
// Sign up is available from the login page. Keeping it here as a third link
// makes the smallest piece of navigation ask a stranger to choose between two
// account actions before they have decided to use either.
func TestTheLandingOffersToolsAndOneWayIn(t *testing.T) {
got := topRight()
if !strings.Contains(got, `href="/signup"`) {
t.Errorf("the front door has no way to sign up on it: %q", got)
for _, want := range []string{`href="/tools"`, `href="/login"`} {
if !strings.Contains(got, want) {
t.Errorf("the front door is missing %s: %q", want, got)
}
}
if strings.Index(got, "/signup") > strings.Index(got, "/login") {
t.Errorf("Log in comes before Sign up on the front door: %q", got)
if strings.Contains(got, `href="/signup"`) {
t.Errorf("the front door has three corner links instead of Tools and Log in: %q", got)
}
if strings.Index(got, "/tools") > strings.Index(got, "/login") {
t.Errorf("Log in comes before Tools on the front door: %q", got)
}
// No redirect on the way in. This is the one page where signing in should
// move you somewhere else, and it already does — carrying the page you were
// on would be a round trip back to a redirect.
// move you somewhere else, and it already does.
if strings.Contains(got, "redirect=") {
t.Errorf("the front door sends you back to itself after signing in: %q", got)
}
}

// And not where the door is shut.
func TestTheLandingDoesNotOfferSignupOnAnInviteOnlyInstance(t *testing.T) {
t.Setenv("INVITE_ONLY", "true")
if got := topRight(); strings.Contains(got, "/signup") {
t.Errorf("an invite-only instance offers a form nobody can complete: %q", got)
}
}
Loading