Lifecycle

Summary

This goes over the lifecycle of a Dendron Nextjs Page from note to published site.

There are three phases to generate the static assets:

  • build metadata
  • compile static assets
  • load webapp

Build

The build phase compiles the necessary metadata from your Dendron workspace so that our nextjs template can generate all pages statically ahead of time.

It involves the following steps

  • the user runs dendron publish build
  • dendron inspects dendron.yml to figure out subset of notes to build
  • generate payloads and metadata for static site

The actual build process is done using the Nextjs Pod (click through for more details on the process)

The following is some pseudocode that goes over some of the steps.

publish build

How notes are filtered for publishing

SiteUtils.filterByConfig {
  ...
}

filterByConfig

  • last updated: 2022-01-01
// get hierarchies that will be published
siteHierarchies := sconfig

domainsAndhiearchiesToPublish = siteHierarchies.map h => {
  return filterByHiearchy(h)
}

...

filterByHiearchy

filterByHiearchy(domain, notes) {
  hconfig := getConfigForHierarchy

  notes = notesGet(domain, notes)
  if notes.length > 1 {
    domainNote = handleDup(...)
  } else {
    domainNote = notes[0]
  }

  ...
  processQ = [domainNote]
  while processQ {
    note = processQ.pop
    maybeNote = filterByNote(note)
    if (!maybeNote) return;

    children = getChildren(maybeNote)
    ...
    children.filter(canPublish)!

    children.forEach {
      processQ.push it
    }
  }
}

canPublish

canPublish(note) [
  // does note have frontmatter?
  note.custom.published = false ? return false

  // is vault private?
  noteVault := note
  noteVault.visibility = PRIVATE ? return false

  hconfig := note
]

Compile

The compile phase generates the static HTML that is deployed to the server. This is handled by next export.

The bulk of the work is done by inside the [id] page by making use of the data fetching capabilities of NextJS that lets us compile all pages ahead of time during export.

  • [[../packages/nextjs-template/pages/notes/[id].tsx]]
getStaticPaths {
  getNotePaths {
    getNotes {
      read DATA_DIR/notes.json
    }
  }
}

getStaticProps {
  id := 
  getNoteBody(id), getNoteMeta(id)
  getNotes
  getCustomHead
}


getNoteBody {
  DATA_DIR/notes/{id}.html
}

getNoteMeta {
  DATA_DIR/meta/{id}.json
}

getCustomHead {
  config := 
  ...
  publicDir = getPublicDir
}

Load

Load

The load phase is what happens inside the webapp when you first load the page.

State and UI is handled by React and Redux.

Pseudocode

  • ../packages/nextjs-template/pages/_app.tsx (Private)

  • the app uses metadata files generated in the build step. You can see whats in these files here (Private)

  • NOTE: this is VERY UNOPTIMIZED at the present (we load up all notes and put them into redux - the only saving grace is that this is not blocking - the initial payload for each individual site is compiled and will load when te site does)

DendronApp {

  useEffect {
    log "fetchNotes:pre"
    data = fetchNotes { fetch("/data/notes.json") }
    log "fetchNotes:got-data"
    setNoteData data
    fetchConfig { fetch("/data/dendron.json") }
  }

  // render note
  ...
}

Note

  • components/DendronNotePage.tsx
Note {
  id = getActiveNoteId
  // render note based on id
}


Children
  1. Load Page

Backlinks