GithubHelp home page GithubHelp logo

sanity-io / sanity Goto Github PK

View Code? Open in Web Editor NEW
4.9K 4.9K 385.0 83.61 MB

Sanity Studio – Rapidly configure content workspaces powered by structured content

Home Page: https://www.sanity.io

License: MIT License

JavaScript 4.06% CSS 0.01% HTML 4.81% TypeScript 91.13%
cms headless react reactjs real-time realtime

sanity's Introduction

Sanity

Build powerful production-ready content workspaces

The Sanity Composable Content Cloud lets teams create remarkable digital experiences at scale. Sanity Studio is an open-source, single-page application that is fast to set up and quick to configure. The Studio comes with a complete studio customization framework that lets you tailor the workspace as your needs grow.

Sanity hosts your content in a real-time, hosted data store called Content Lake. Get started with the free plan with generous bandwidth and hosting included and pay-as-you-go for overages.

Quickstart

Initiate a new project by running the following command:

npm create sanity@latest

# With other package managers:
yarn create sanity@latest
pnpm create sanity@latest

Go here for a step-by-step guide on how to get up and running.

Check out the docs and plugins and start building.

Key Features

Sanity Studio

Sanity Studio is an open-source real-time CMS, that you can customize with JavaScript and React.

Stay up to date

Code of Conduct

We aim to be an inclusive, welcoming community for everyone. To make that explicit, we have a code of conduct that applies to communication around the project.

Want to contribute?

Found a bug, or want to contribute code? Pull requests and issues are most welcome. Read our contributing guidelines to learn how.

Help Improve Sanity Studio translations

We're always looking to make Sanity Studio more accessible and user-friendly, and your contributions can make a big difference. Whether you're a seasoned developer or just starting out, helping with translations is a fantastic way to get involved.

If you're fluent in a language other than English, we'd love your help in reviewing and improving translations. Your expertise can greatly enhance the experience for users worldwide.

How to Contribute:

  1. Visit our sanity-io/locales repository and try out a locale you are fluent in.
  2. Have ideas for improvements? Submit a PR following the contributing guide.
  3. See if there are open PRs in languages you are fluent in and help review them.

Interested in playing a bigger role? You can ask to be added as a maintainer to oversee translations for specific languages, where you will be automatically added as a reviewer on PRs that involve your language. See the sanity-io/locales README for more.

Your contributions not only improve Sanity Studio but also bring together a diverse and global community of users. We appreciate every effort, big or small, and we can't wait to see what you bring to the table!

License

Sanity Studio is available under the MIT License

sanity's People

Contributors

binoy14 avatar bjoerge avatar cngonzalez avatar ecospark[bot] avatar evenwestvang avatar github-actions[bot] avatar hermanwikner avatar jtpetty avatar judofyr avatar juice49 avatar kmelve avatar kristofferjs avatar mariuslundgard avatar mikolajdobrucki avatar ninaandal avatar pedrobonamin avatar renovate[bot] avatar rexxars avatar ricokahler avatar ritadias avatar robinpyon avatar runeb avatar saasen avatar sgulseth avatar simen avatar sjelfull avatar skogsmaskin avatar snorrees avatar stipsan avatar vicmeow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sanity's Issues

[import] Provide some details when asset upload fails

Whenever this happens:

Importing documents ▪▪▪▪▪▫▫▫▫▫▫▫▫▫▫▫▫▫▫ 28% in 139.16s  sanity:client [672] HTTP POST https://wd60ezy4.api.sanity.io/v1/assets/images/production?label=5080645b4c9853456b0d71bd13234a24 +126ms
  sanity:client [672] Request headers: {
  "Accept": "application/json",
  "Authorization": "Bearer xxxxxxx"
} +0ms
Importing documents ▪▪▪▪▪▫▫▫▫▫▫▫▫▫▫▫▫▫▫ 28% in 139.64s  sanity:client [672] Response code: 400 Bad Request +428ms
  sanity:client [672] Response body: {
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid image, could not read metadata",
  "details": "Input buffer contains unsupported image format"
} +0ms
  sanity:client [672] ERROR: Bad Request - Invalid image, could not read metadata +0ms

...it would be nice to have some info (_id, url, somesuch) regarding the request so it's possible to figure out exactly which image (or other piece of data) caused the breakdown during import.

[cli] Dataset import should not fail on failed asset download

Say your image assets are sourced from Amazon S3. Currently, if the importer gets a failed download (say 403) the whole import will die immediately. This might be the desired default (not sure about that), but we should have a "keep going on missing asset"-flag which just saves the current document without the desired asset. Finally, when the import is done, produce a report which lists:

  • document(s) which encountered a problem
  • which asset URLs failed
  • response status code (403 or whatever)

Same behaviour should occur if assets are local files.

Maybe name the flag keep-going-on-missing-asset, dont-stop-on-missing-asset or tolerate-missing-assets?

[resolver] Warn on duplicate implementers

It's currently possible to implement a part more than one time, with the same file. While not necessarily a big deal, it's unnecessary and easily checkable, so we should probably warn/throw when this situation comes up.

[client] Don't retry on 500 errors when POSTing

When doing POST-operations and we encounter a 5xx error, we shouldn't automatically retry. This can lead to totally unpredictable results if the server actually receives and processes the request, but fails on something like formatting the reply or similar.

Version check fails for canary releases

A request to e.g.

https://81xbpgf3.api.sanity.io/v1/versions?m=%40sanity%2Fbase%400.109.0-alpha.17fcc625

Fails with

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "child \"m\" fails because [single value of \"m\" fails because [\"m\" 
     with value \"@sanity/base@0.109.0-alpha.17fcc625\" fails to match
     the required pattern: /^(@sanity\\/|sanity-)[a-z0-9-]+@\\d+\\.\\d+\\.\\d+$/i]]",
  "validation": {
    "source": "query",
    "keys": [
      "m"
    ]
  }
}

Have we gotten the date type right?

While working yesterday with importing data from firebase to Sanity, it struck me that our date-type has some issues wrt. developer ergonomics.

When importing documents that already had several fields with unix timestamps, I had to convert all of them to objects of this shape before importing:

{
  _type: 'date',
  local: '2017-02-08T01:30:00+01:00'
  offset: 120
  timezone: 'Europe/Oslo'
  utc: '2017-02-08T00:30:00Z'
}

WHY do I need to store it like this?

TBH this felt like a violation of the easy things are easy-principle. There's probably a ton of cases where it makes perfectly good sense to store dates like this, but at least I'd like to know the reasoning behind it (documentation issue).

HOW do I format a date like this?

Do I need a timezone library? Have to drag in moment? Which fields here is absolutely required? What if I only have UTC date, do I need to add timezone still? What should that be, system timezone?

There are date fields on documents already (_createdAt, _updatedAt). Of what type are these? Apparently not date.

Sometimes you just want a field to be stored as a utc date (just like _createdAt, etc.), but we have no schema type for it. So: If I actually just want to store an utc date as a field (and still have it editable with a date picker in the studio), there's currently no way to do it.

Additionally some queries ends up looking a bit awkward:

*[_type == 'article'] | order(_createdAt desc, publishAt.utc asc)

...and really easy to get wrong:
(this will not work as expected, nor return any errors telling you about your mistake!)

*[_type == 'article'] | order(_createdAt desc, publishAt asc)

Possible solution

I think we should optimize for the most common use cases, but still support the less common (but nonetheless important) use cases.

We can do this by introduce a schema type for utc date strings (date, dateTime, instant?). My guess is that this would cover the majority of use cases involving dates. If one wants to preserve timezone information, we should provide a separate builtin schema type (maybe zonedDateTime?), which is an object that includes timezone information much like the date type we have today. (This data type could actually just be modelled by the schema author too, but I'm ok with making it a builtin type).

Terminology

It may be a good idea try align our terminology as closely as possible to the current ECMAScript temporal proposal which is based on established terminology from years of accumulated experience from other programming languages:

https://github.com/maggiepint/proposal-temporal

Thoughs?

[client] Extend error object with relevant properties

Not sure how much refactoring is needed to support this, but it would be nice to attach relevant properties such as the operation (mutation? query? listener?) as well as the actual mutation(s) or query ran to the error object returned on a failed response.

test

test slack / gh integration

Support indeterminate state on checkboxes

The default boolean input that we use in the form builder has no support for an indeterminate state, (e.g. value is not set). There are valid use cases for this, so we should support it too. Since the boolean input has two different layouts, namely checkbox and switch (default) these should also support displaying an indeterminate state.

The native <input type="checkbox" already supports it (programmatically).

Discrepancy in handling inserts in arrays between backend an mutator?

There might be a discrepancy between the backend and mutator. Given an array with one element, it seems that inserting an element before element 1 results in no elements being inserted in the backend (which is the correct behaviour), while mutator actually inserts the element at the end of the array.

Validate format of returned values from preview

Right now, if e.g. an object is returned as title this gets inserted into the dom without any checks, and thus it fails with "Objects are not valid as react components". We should probably do some basic type validation to prevent this from failing. Preferably show some helpful warnings while in development and maybe just handle silently in production.

Omitting tool icon should not fail

The tool switcher seems to try to use <tool.icon /> without any checks, expecting tool.icon to be a valid react component, which fails if its not.

Side note: It currently looks like no tool icons are displayed at all.

[core] Hint about `npm install` if plugin is not found

When you run start or build and Sanity encounters a plugin that cannot be resolved, the following error is given:

Error: Plugin "vision" not found.
Locations tried:
  * /home/espenh/webdev/san/packages/example-studio/plugins/sanity-plugin-vision
  * /home/espenh/webdev/san/packages/example-studio/plugins/vision

Helpful - but we could take this even further - we could check package.json to see if the plugin exists there. If it does, we could add a Hint: Have you remembered to run "npm install"? or similar.

[core] Asset importing does not handle concurrency well

When importing documents that has multiple copies of the same image references within either the same document or within documents that are (by chance) imported in parallel, a state where two asset documents with the same label can occur.

This should probably be fixed by first extracting all the URLs to upload, filter out duplicates and upload the remaining items, before proceeding.

Find an alternative to value containers

Sometimes input components needs a way to represent their value in a custom, optimized way. For example, Slate uses an Immutable.js based structure to represent its state/document, and cannot serialize/deserialize its complete state on each onChange => props.value update cycle.

Our current solution to this is the concept of a "value container", which is a wrapper class that are declared on the input component itself, which initially will receive the serialized value, given an opportunity to deserialize it and keeping the wrapped value throughout the lifetime of the component. The value containers offers a way for custom inputs to apply incoming patches in a way that is optimized for the internal structure.

This approach has been working quite allright up until now, but now the complexity of this is starting to become a major pain point. Some of the drawbacks are:

  • We need to value.serialize() in order to unpack the value all over, e.g. for displaying an object's title

  • For the object container, its even worse: value.getAttribute('title').serialize()

  • Since the value containers are resolved "up front" through resolveInputComponent, there's no easy way to conditionally replace an input component runtime.

  • Debugging experience is worse than it would be if everything is just plain objects

  • Implicit fields (those not defined in the schema) are not exposed through value containers e.g. _createdAt (guess we could fix this even though it would be an abstraction violation)

I've got a vague idea on an alternative approach that may (or may not) work, I'll try to find some time to explore it.

If anyone else has any ideas, please let me know.

[components] Inconsistent naming convention for boolean props

Right now some of our components expects props like scrollable, while others expect e.g. isOpen. We should agree on one convention and stick to it.

Personally, I prefer isScrollable over scrollable.

Opinions?


This issue has been concluded with: #20 (comment)

If the semantics is 1:1 with native, use the native prop name, otherwise, use is/has/*-prefix

HTML-converter returns a nested block structure

When pasting from HTML and the markup nests tags that gets converted to blocks, it inserts a nested block structure into slate. This in turn causes serializing to blow up, since we don't allow nested blocks.

This is what the slate state looks like at the time of serializing:

image

I guess this could be solved by simply flattening the structure after paste?

Proposal: Local customizations

Currently most of sanity can be customized on a studio/runtime level. This is fine for global concerns like branding colors, etc, but sometimes you want different custonizations in local contexts, for example, instantiating the form builder with a custom field renderer inside the edit modal for documents of type xyz, rather than the full-fledged default form-builder.

[mutator] setIfMissing messes with squashing

The mutator considers "setIfMissing" a non-squashable patch since it conceptually could change the shape of the document. This messes up squashing since Sanity always sends a set if missing patch before each delta patch. It is conceptually correct to squash setIfMissing patches as long as the resulting patch contains one of each setIfMissing when it first arrive.

[setIfMissing("field"), diffMatchPatch("field", ...), setIfMissing("field"), diffMatchPatch("field", ...), setIfMissing("field"), diffMatchPatch("field", ...)] can be squashed to [setIfMissing("field"), diffMatchPatch("field", ...)]

Data aspects faceplants if it cannot resolve display field for type. Infers `null` as display attribute

I get the error:

Uncaught Error: resolved display field for type "site" to "null",
 but field does not exist in schema. check data-aspects config

When trying to edit a document with the following type definition:

{
  type: 'object',
  name: 'site',
  fields: [
    {
      name: 'discoveredAt',
      title: 'Discovered at',
      type: 'date'
    },
    {
      name: 'publishedAt',
      title: 'Published at',
      type: 'date'
    },
    {
      name: 'url',
      title: 'Url',
      type: 'url'
    }
  ]
}

We should probably handle this a bit more gracefully

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.